开放平台
首页平台概述
开发者
  • API文档
  • SDK
产品功能
  • 新手入门
  • 产品功能
常见问题
首页平台概述
开发者
  • API文档
  • SDK
产品功能
  • 新手入门
  • 产品功能
常见问题
  1. APP嵌入支付说明
  • demo
  • JS SDK
    • 产品介绍
    • 快速接入
    • SDK 对接示例
    • 观看直播
    • 暖场视频
    • 房间消息说明
    • 互动连麦
    • 文档白板
    • 全局事件
    • 全局错误码
    • 版本更新记录
    • 互动工具
      • 互动-抽奖
      • 互动-礼物
      • 互动-签到
      • 互动-问卷
      • 互动-公告
      • 互动-商品
      • 互动-问答
      • 互动-推屏卡片
      • 互动-快问快答
      • 互动-聊天
      • 互动-优惠券
      • 互动-点赞
    • 直播间拓展功能
      • 资料下载
      • 观看限制验证
      • 观看协议
      • 回放章节
  • 点播SDK
    • 点播上传SDK
    • 更新记录
  • iOS SDK
    • 整体介绍
    • 快速接入
    • SDK 登录
    • 暖场视频
    • 视频轮询
    • 直播彩排
    • 高级美颜
    • 云导播
    • 观看协议
    • 文档白板演示
    • 聊天功能
    • 视频直播
      • 发起视频直播
      • 观看视频直播
    • 互动直播
      • 观众互动
      • 推流摄像头
      • 互动直播API
      • 主播发起互动直播
      • 嘉宾加入互动直播
    • 无延迟直播
      • 主播发起无延迟直播
      • 观众观看无延迟直播
    • 互动工具
      • 互动-抽奖
      • 互动-礼物
      • 互动-签到
      • 互动-问卷
      • 互动-章节打点
      • 互动-公告
      • 互动-商品
      • 互动-计时器
      • 互动-问答
      • 互动-推屏卡片
      • 互动-快问快答
      • 互动-优惠券
      • 互动-点赞
    • 直播间拓展能力
      • 直播间特色功能配置项
      • 文件下载
      • 修改角色昵称
      • 观看权限校验
      • 投屏
      • 虚拟人数
    • 观看回放
      • 观看回放
    • 防录屏
      • 跑马灯
    • 字段说明
      • 互动活动详情字段
      • 错误码说明
      • 常量定义
      • 活动详情字段说明
    • 版本更新说明
      • 版本更新信息
      • v2.3.0 到 v2.4.0 升级说明
      • v3.0.1 到 v3.2.0 升级说明
      • V2.9.0到v3.0.1升级说明
      • v6.3.0
      • v6.2.1
      • v3.2.0 到 v4.0.1
      • v2.7.0 到 v2.8.0、v2.9.0 升级说明
      • 6.5.0
      • v5.0.x 到 v6.0.0
      • v6.4.0
  • Adroid SDK
    • 整体介绍
    • 快速接入
    • SDK登录
    • 暖场视频
    • 视频轮巡功能
    • 直播彩排
    • 高级美颜
    • 云导播功能
    • 观看协议
    • 文档白板
    • 聊天功能
    • 房间消息
    • 信息采集说明
    • 视频直播
      • 发起视频直播
      • 观看视频直播
    • 互动直播
      • 互动直播API
      • 主播发起互动直播
      • 嘉宾加入互动直播
      • 观众观看互动直播
    • 无延迟直播
      • 主播发起无延迟直播
      • 观众观看无延迟直播
    • 互动工具
      • 互动-抽奖
      • 互动-礼物
      • 互动-签到
      • 互动-问卷
      • 互动-公告
      • 互动-商品
      • 互动-计时器
      • 互动-问答
      • 互动-推屏卡片
      • 互动-快问快答
      • 互动-优惠券
      • 互动-点赞
    • 直播拓展功能
      • 修改角色名称
      • 文件下载
      • 投屏演示
      • 虚拟人数
      • 观看权限校验
      • 直播间特色功能配置项
    • 观看回放
      • 观看回放/点播
    • 防录屏
      • 直播水印
      • 跑马灯
    • 字段说明
      • 房间消息字段说明
      • 聊天消息字段说明
      • 活动详情字段说明
    • 版本更新说明
      • 更新记录
      • v6.4.0
      • v6.3.0
      • v6.2.3
      • v6.2.1
      • v6.2.0
      • v6.1.0
      • v6.0.0
      • v5.0.0
      • v4.1.0
      • v4.0.0
      • v3.3.0
  • APP嵌入支付说明
    • 支付调起说明
    • Scheme规则说明
  1. APP嵌入支付说明

支付调起说明

支付调起说明#

iOS:#

核心逻辑是通过
- (void)webView:(WKWebView _)webView decidePolicyForNavigationAction:(WKNavigationAction _)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
方法去监听跳转地址和点击提交重定向的地址
通过 application openURL:方法跳转微信及支付宝应用
通过
- (BOOL)application:(UIApplication _)app openURL:(NSURL _)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> \*)options
方法获取对应 scheme 回传的数据

示例代码#

#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSLog(@"发送请求-----》%@", navigationAction.request.URL.absoluteString);


    NSURLRequest *request           = navigationAction.request;
    NSURL *url                      = request.URL;
    NSString *scheme                = [navigationAction.request.URL scheme];
    UIApplication *application      = [UIApplication sharedApplication];
    NSString *absoluteString        = navigationAction.request.URL.absoluteString;

    // decode for all URL to avoid url contains some special character so that it wasn't load.
    NSLog(@"Current URL is %@",absoluteString);

    static NSString *endPayRedirectURL = nil;

    //三方购买
    if ([scheme isEqualToString:@"test02-live.vhall.com"]) {
        // 打开客户端
        [application  openURL:url
                      options:@{}
            completionHandler:^(BOOL success) {
            NSLog(@"客户端跳转%@", success ? @"完成" : @"失败");
        }];

        // 取消当前请求
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    // 解决跳转到本地支付宝App不返回的问题
    // 判断URL是否以alipays://或者alipay://开头
    if ([absoluteString hasPrefix:@"alipays://"] || [absoluteString hasPrefix:@"alipay://"]) {
        // 定义支付宝URL的前缀
        NSString *prefixString = @"alipay://alipayclient/?";

        // 将URL中的alipays替换为test02-live.vhall.com
        NSString *urlString = [[self xh_URLDecodedString:absoluteString] stringByReplacingOccurrencesOfString:@"alipays" withString:CompanyFirstDomainByWeChatRegister];


        // 如果URL以前缀字符串开头,则对URL进行特殊处理
        if ([urlString hasPrefix:prefixString]) {
            // 获取前缀字符串的范围
            NSRange rang = [urlString rangeOfString:prefixString];
            // 获取前缀字符串后面的部分
            NSString *subString = [urlString substringFromIndex:rang.length];
            // 将前缀和后面的部分拼接起来,并对拼接后的字符串进行URL编码
            NSString *encodedString = [prefixString stringByAppendingString:[self xh_URLEncodedString:subString]];
            // 将编码后的字符串转换为NSURL对象
            url = [NSURL URLWithString:encodedString];
        }

        // 打开支付宝客户端
        [application  openURL:url
                      options:@{}
            completionHandler:^(BOOL success) {
            NSLog(@"支付宝跳转%@", success ? @"完成" : @"失败");
        }];

        // 取消当前请求
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }


    //解决微信支付后为返回当前应用的问题
    // 判断是否需要重定向
    if ([absoluteString hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![absoluteString hasSuffix:[NSString stringWithFormat:@"redirect_url=%@://",CompanyFirstDomainByWeChatRegister]]) {
        // 取消当前请求
        decisionHandler(WKNavigationActionPolicyCancel);

        NSString *redirectUrl = nil;
        // 判断URL中是否包含redirect_url参数
        if ([absoluteString containsString:@"redirect_url="]) {
            NSRange redirectRange = [absoluteString rangeOfString:@"redirect_url"];
            // 获取redirect_url参数后面的值
            endPayRedirectURL =  [absoluteString substringFromIndex:redirectRange.location+redirectRange.length+1];
            // 将redirect_url参数的值替换为当前应用程序的URL Scheme,并重新构造URL
            redirectUrl = [[absoluteString substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=%@://",CompanyFirstDomainByWeChatRegister]];
        }else {
            // 在URL末尾添加redirect_url参数,并将其值设置为当前应用程序的URL Scheme
            redirectUrl = [absoluteString stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=%@://",CompanyFirstDomainByWeChatRegister]];
        }

        // 构建新的请求
        NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT];
        newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
        [newRequest setValue:[NSString stringWithFormat:@"%@",CompanyFirstDomainByWeChatRegister] forHTTPHeaderField:@"Referer"];
        newRequest.URL = [NSURL URLWithString:redirectUrl];
        // 使用新请求加载页面
        [webView loadRequest:newRequest];
        return;
    }


    // 判断scheme是否为http或者https
    if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
        // 取消当前请求
        decisionHandler(WKNavigationActionPolicyCancel);
        // 判断scheme是否为weixin
        if ([scheme isEqualToString:@"weixin"]) {
            // 如果endPayRedirectURL不为空,使用其加载新页面
            if (endPayRedirectURL) {
                [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:endPayRedirectURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT]];
            }
        }else if ([scheme isEqualToString:[NSString stringWithFormat:@"%@",CompanyFirstDomainByWeChatRegister]]) {
            // 对于其他scheme,可以进行特殊处理
        }
        // 如果URL中包含weixin://,打开微信客户端
        if ([navigationAction.request.URL.absoluteString hasPrefix:@"weixin://"]) {
            [application  openURL:url
                          options:@{}
                completionHandler:^(BOOL success) {
                NSLog(@"微信跳转%@", success ? @"完成" : @"失败");
            }];
        }
        return;
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}
// URL解码
- (NSString *)xh_URLDecodedString:(NSString *)urlString {
    NSString *string = urlString;
    // 调用CFURLCreateStringByReplacingPercentEscapesUsingEncoding函数对URL进行解码
    NSString *decodedString = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)string, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    return decodedString;
}
// URL编码
- (NSString *)xh_URLEncodedString:(NSString *)urlString {
    NSString *string = urlString;
    // 调用CFURLCreateStringByAddingPercentEscapes函数对URL进行编码
    NSString *encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,(CFStringRef)string,NULL,(CFStringRef)@"!*'();:@&=+$,/?%#[]",kCFStringEncodingUTF8));
    return encodedString;
}

Android:#

核心逻辑是通过 WebViewClient#shouldOverrideUrlLoading 方法去监听跳转地址和点击提交重定向的地址
通过 startActivity(intent)方法跳转微信及支付宝应用
注:微信支付需要验证 Referer,加载嵌入页时需传入 Referer(具体值与微信后台设置一致)

示例代码#

//1. WebView 传入Referer
Map<String,String> webviewHead =new HashMap<>();
webviewHead.put("Referer", "https://live.vhall.com");
webView.loadUrl(url,webviewHead);

//2. 监听scheme 跳转 原生唤起 app 支付
webView.setWebViewClient(new WebViewClient() {

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        String url = request.getUrl().toString();
        if(!url.startsWith("http"))
        {
            PackageManager packageManager = getPackageManager();
            Log.e("========",url);
            try {
               //打开 scheme
               Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url));
                startActivity(intent);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(getApplicationContext(), "未安装应用", Toast.LENGTH_SHORT).show();
            }
            return true;
        }
        return false;
    }
	.....
}

H5 唤起微信支付技术要点#

配置 URL Types 应用程序的 URL Scheme,可以通过 Scheme 进行返回应用,此处演示微信和支付宝。
图一

修改 redirect_url#

确保 redirect_url 这个回调链接与设定的 URL Schemes 保持一致,此步骤为关键步骤,只有正确设置后才能返回 APP
拦截后,我们首先需要关注原始地址是否包含 redirect_url=字符串。
如果包含,说明后台人员利用该字符串在微信支付完成后跳转到支付完成的界面。
我们也需要利用该字段实现支付完成后跳转回 APP。
• 如果包含 redirect_url=字段,我们需要首先记录后台重定向的地址,然后将其替换为我们配置好的 URL Schemes 以实现跳转回我们的应用。在跳转回我们应用后,我们会手动再加载一次原始重定向的 URL 地址。
• 如果不包含 redirect_url=字段,我们只需将该字段添加到原始 URL 的末尾。

设置 webView 请求 header 中的 Referer 字段#

微信支付结束后默认回调 Referer 字段中的地址。
Referer 设置为www.xxxx.com://的格式。

注意#

判断微信地址的同时判断redirect_url=www.xxxx.com://,因为在第一次检测到后会重新加载该地址,该地址中同时包含 https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb,会形成循环冲突。
所以判断条件如下:
• 如果项目中有支付完成的重定向地址,可以在跳转前加载该地址,否则在回到应用后会有明显的加载过程,界面不友好。
• 一般跳转到其他 APP 时,地址不是以 http 或 https 开头,所以在最后的判断中以此为依据,但注意如果服务器端加载错误的地址走入此逻辑,则必须对特定的 scheme 进行处理

H5 唤起支付宝支付技术要点#

配置 scheme#

参考 图一 实现。

注意#

如果 URL 以alipays://或者alipay://开头,则将 URL 中的alipays替换为微吼的域名live.vhall.com,并对 URL 进行特殊处理;
否则不进行处理。
特殊处理完成后,使用 openURL 方法打开支付宝客户端,并将当前请求取消。其中 openURL 方法是 UIApplication 的方法,用于打开其他应用程序或者系统服务。
修改于 2025-05-27 13:00:42
上一页
v3.3.0
下一页
Scheme规则说明
Built with