一、什么是 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 跳转流程如下:

  1. 用户在前端点击支付按钮
  2. 前端 AJAX 请求后端生成支付订单,获取支付宝付款链接
  3. 前端判断用户设备类型(iOS/Android),选择合适的 Deep Link 方案
  4. 尝试通过 Universal Links / App Links / URL Scheme 唤起支付宝
  5. 等待用户完成支付,支付宝将结果回调到 notify_url
  6. 前端轮询或使用 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 跳转、智能入口池分发和自动发货功能,开箱即用,省去大量开发时间。欢迎前往 源码商城 了解更多产品详情。