一、什么是 Deep Link?
Deep Link(深度链接)是指一种能够直接跳转到移动应用内特定页面的 URL 技术。与传统的只打开 App 首页不同,Deep Link 可以携带参数直接导航到目标页面,例如支付宝的转账页面、付款码页面或生活缴费页面。
在支付和转卡码场景中,Deep Link 尤其重要。用户在浏览器中点开一个链接,系统会判断是否已安装支付宝客户端:已安装则直接唤起 App 并跳转到指定页面,未安装则优雅降级到 H5 页面。这种无缝衔接的体验,是提升支付成功率和转卡码核销转化率的关键技术之一。
二、Deep Link 的三种实现方式
2.1 URL Scheme(最传统的方式)
URL Scheme 是 iOS 和 Android 平台最早支持的 Deep Link 方案。每个 App 在安装时注册一个自定义协议(Scheme),例如支付宝的 Scheme 为 alipays:// 或 alipay://。
一个典型的支付宝转卡码 Deep Link 示例:
alipays://platformapi/startapp?saId=10000007&qrcode=https://qr.alipay.com/xxx123
上面这个链接会直接唤起支付宝并打开扫码页面(saId=10000007 是扫一扫的固定 ID),并将参数中的二维码 URL 传递给扫码接口。
优点:实现简单,iOS/Android 均支持。缺点:不同厂商 ROM 可能拦截未知 Scheme;首次打开会弹出确认对话框;部分浏览器限制自定义 Scheme 的跳转。
2.2 Android App Links
Android 6.0+ 引入的 App Links 是 Google 官方的 Deep Link 方案。它使用 HTTP/HTTPS 链接,通过在服务端放置 Digital Asset Links 文件来验证 App 与域名的绑定关系,从而免去用户确认弹窗,实现直接跳转。
配置分为两步:
第一步: 在 Android App 的 AndroidManifest.xml 中声明 Intent Filter:
<!-- AndroidManifest.xml -->
<activity android:name=".PayActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="pay.greenfield.ltd"
android:pathPrefix="/alipay/pay" />
</intent-filter>
</activity>
第二步: 在域名根目录部署 Digital Asset Links JSON 文件:
# 文件位置: https://pay.greenfield.ltd/.well-known/assetlinks.json
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.greenfield.pay",
"sha256_cert_fingerprints": [
"14:6D:E9:9C:...:A5:3B"
]
}
}
]
2.3 iOS Universal Links
Apple 在 iOS 9 推出的 Universal Links 是 iOS 端的官方 Deep Link 方案。与 App Links 类似,它也使用标准 HTTPS 链接,并通过上传 apple-app-site-association 文件来声明 App 与域名的绑定关系。
# 文件位置: https://pay.greenfield.ltd/.well-known/apple-app-site-association
{
"applinks": {
"apps": [],
"details": [
{
"appID": "ABCDEF1234.com.greenfield.pay",
"paths": ["/alipay/*"]
}
]
}
}
随后在 Xcode 中开启 Associated Domains,添加 applinks:pay.greenfield.ltd 即可。
三、支付场景中的 Deep Link 实战应用
3.1 转卡码支付跳转流程
在转卡码系统中,用户点击"立即支付"后,系统需要将用户从 H5 页面引导到支付宝 App 完成付款。一套完整的 Deep Link 跳转流程如下:
- 用户在前端点击支付按钮
- 前端 AJAX 请求后端生成支付订单,获取支付宝付款链接
- 前端判断用户设备类型(iOS/Android),选择合适的 Deep Link 方案
- 尝试通过 Universal Links / App Links / URL Scheme 唤起支付宝
- 等待用户完成支付,支付宝将结果回调到 notify_url
- 前端轮询或使用 WebSocket 获取支付结果,更新订单状态
以下是后端生成支付宝支付链接的 PHP 代码示例:
<?php // 支付宝转卡码支付 - 生成 Deep Link 跳转链接 function generateAlipayDeepLink($orderNo, $amount, $subject) { // 1. 构建支付宝支付请求参数 $params = [ 'app_id' => '20210071xxxxxx', 'method' => 'alipay.trade.precreate', 'format' => 'JSON', 'charset' => 'utf-8', 'sign_type' => 'RSA2', 'timestamp' => date('Y-m-d H:i:s'), 'version' => '1.0', 'notify_url' => 'https://yourdomain.com/alipay/notify', 'biz_content' => json_encode([ 'out_trade_no' => $orderNo, 'total_amount' => $amount, 'subject' => $subject, 'qr_code_type' => 'PAYMENT_CODE', ]), ]; // 2. 签名(省略完整 sign 方法) $params['sign'] = generateSign($params, $privateKey); // 3. 生成支付宝支付链接 $gateway = 'https://openapi.alipay.com/gateway.do?' . http_build_query($params); // 4. 构建 Deep Link - 使用 alipays Scheme 唤起 App $alipayDeepLink = 'alipays://platformapi/startapp?' . http_build_query([ 'appId' => '20000067', // 支付宝收银台 ID 'url' => urlencode($gateway), // 加密后的支付 URL ]); return $alipayDeepLink; }
3.2 前端智能设备检测与降级方案
在实际部署中,我们不能假设用户一定安装了支付宝 App。一个健壮的 Deep Link 实现必须包含设备检测和优雅降级:
// JavaScript 前端 Deep Link 跳转与降级 function alipayDeepLinkJump(alipayLink, h5FallbackUrl) { const ua = navigator.userAgent.toLowerCase(); const isiOS = /iphone|ipad|ipod/.test(ua); const isAndroid = /android/.test(ua); // 浏览器窗口隐藏检测(判断 App 是否被唤起) let isAppOpened = false; let timer = null; // 监听页面可见性变化 const visibilityHandler = () => { if (document.hidden) { isAppOpened = true; if (timer) clearTimeout(timer); } }; document.addEventListener('visibilitychange', visibilityHandler); // 尝试唤起支付宝 App if (isiOS) { // iOS 优先使用 Universal Links window.location.href = h5FallbackUrl; // 实际部署时 Universal Links 替换此 URL } else if (isAndroid) { // Android 优先使用 App Links,降级到 URL Scheme const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = alipayLink; document.body.appendChild(iframe); } else { // PC 或未知设备 - 直接跳转 H5 页面 window.location.href = h5FallbackUrl; return; } // 超时检测:2.5 秒后若 App 未被唤起,跳转 H5 timer = setTimeout(() => { document.removeEventListener('visibilitychange', visibilityHandler); if (!isAppOpened) { window.location.href = h5FallbackUrl; } }, 2500); }
这段代码的核心思想是:优先尝试唤起支付宝 App,同时用 visibilitychange 事件监测 App 是否成功唤起。如果 2.5 秒内没有检测到页面隐藏(即 App 未打开),则自动跳转到 H5 支付页面作为降级方案。
四、Deep Link 在转卡码系统中的集成
在 源码商城的转卡码系统 中,Deep Link 技术被广泛应用于以下场景:
4.1 支付入口智能分发
当用户选择购买卡密时,系统会根据用户设备信息、历史支付行为、IP 地域等多维度特征,智能选择最优的 Deep Link 入口。多个入口池通过加权分发算法实现流量调度,每个入口对应不同的支付宝 Deep Link 路径,有效降低单一入口被风控的概率。
入口池分发核心算法:
# Python 智能入口池加权分发 import random from datetime import datetime class EntryPool: def __init__(self): # 入口池配置: {入口ID: {权重, 今日调用次数, 上限}} self.pools = { 'alipay_scheme_a': {'weight': 30, 'calls': 0, 'limit': 500}, 'alipay_scheme_b': {'weight': 25, 'calls': 0, 'limit': 500}, 'alipay_scheme_c': {'weight': 20, 'calls': 0, 'limit': 400}, 'alipay_universal_link': {'weight': 15, 'calls': 0, 'limit': 300}, 'h5_fallback': {'weight': 10, 'calls': 0, 'limit': 200}, } self.today = datetime.now().date() def select_entry(self): # 过滤已达上限的入口 available = {k: v for k, v in self.pools.items() if v['calls'] < v['limit']} if not available: return 'h5_fallback' # 全部超限,兜底到 H5 # 加权随机选择 total_weight = sum(v['weight'] for v in available.values()) r = random.uniform(0, total_weight) cumulative = 0 for name, config in available.items(): cumulative += config['weight'] if r <= cumulative: config['calls'] += 1 return name return list(available.keys())[-1] # 每日重置 def daily_reset(self): for pool in self.pools.values(): pool['calls'] = 0
4.2 回调通知与自动发货
用户通过 Deep Link 跳转到支付宝完成付款后,支付宝会向我们的 notify_url 发送异步通知。系统收到通知后验证签名、更新订单状态、触发自动发货流程。整个链路从用户点击到卡密到账,通常在 3-5 秒内完成。
# Python 支付宝异步通知处理 from flask import Flask, request import hashlib, hmac, json app = Flask(__name__) @app.route('/alipay/notify', methods=['POST']) def alipay_notify(): # 获取支付宝通知参数 data = request.form.to_dict() trade_status = data.get('trade_status') out_trade_no = data.get('out_trade_no') trade_no = data.get('trade_no') total_amount = data.get('total_amount') # 验证签名(简化示例) if not verify_alipay_sign(data): return 'fail' # 处理支付成功 if trade_status == 'TRADE_SUCCESS': # 更新订单状态 update_order_status(out_trade_no, trade_no, total_amount) # 触发自动发货: 生成卡密并发送 card_code = generate_card_code(out_trade_no) send_card_to_user(out_trade_no, card_code) # 记录日志 app.logger.info(f'Order {out_trade_no} paid. Card: {card_code}') return 'success' return 'fail' def verify_alipay_sign(data): # 实际应使用支付宝 SDK 验签 # 此处仅作演示 return True
五、常见问题与排错
5.1 App 无法被唤起
这是最常见的问题。排查思路:
- 确认支付宝 App 已安装且版本在 10.0 以上
- 检查 URL Scheme 是否正确拼写(支付宝支持
alipays://和alipay://) - Android 设备检查是否有第三方 ROM 拦截了 Scheme 跳转(如 MIUI、EMUI 需要在权限设置中放开"允许唤醒")
- iOS 设备检查 Universal Links 的 apple-app-site-association 文件是否可通过 HTTPS 访问
5.2 Deep Link 被浏览器拦截
某些浏览器(如 Chrome、Safari)对自定义 Scheme 的跳转有严格限制。解决方案:
- 优先使用 Universal Links / App Links(标准 HTTPS 链接,不会被拦截)
- 使用
window.location.href替代location.replace()进行跳转 - 通过 iframe 或 meta refresh 作为备选唤起方式
- 添加用户交互触发(必须由用户点击事件触发,禁止自动跳转)
5.3 LocalStorage 隔离问题
当通过 Deep Link 唤起支付宝再切回浏览器时,部分浏览器(尤其是 iOS 的 Safari)会因为进程隔离导致 LocalStorage 数据丢失。建议使用 SessionStorage 或 URL 参数传递关键状态。
六、安全注意事项
Deep Link 在带来便捷体验的同时,也引入了安全风险,需要注意以下几点:
- 参数校验: 所有通过 Deep Link 传递的参数必须在服务端进行严格校验,防止参数篡改攻击
- 签名机制: 在 Deep Link URL 中加入签名参数,确保链接未被第三方篡改
- 防重放攻击: 每个 Deep Link 加入一次性 nonce 参数,并设置合理的过期时间(通常 5 分钟)
- HTTPS 强制: Universal Links 和 App Links 均要求使用 HTTPS 协议
七、总结
Deep Link 技术是构建优质移动端支付体验的基石。从基础的 URL Scheme 到 Android App Links、iOS Universal Links,每种方案都有其适用场景。在实际的转卡码系统中,我们通常采用"多入口池 + 智能分发 + 优雅降级"的组合策略,既保障了支付成功率,又降低了风控风险。
如果你正在搭建自己的转卡码平台或支付系统,源码商城的转卡码系统 V3 已经内置了完整的 Deep Link 跳转、智能入口池分发和自动发货功能,开箱即用,省去大量开发时间。欢迎前往 源码商城 了解更多产品详情。