接入流程

商户后端接入

  • 用户在商户侧完成商品下单;
  • 商户后端调用微信 H5 支付 统一下单接口,获取调起微信 H5 支付的 URL。即统一下单接口返回的 mweb_url 字段值(商户如果不使用微信支付方式,则可忽略该步骤);
  • 商户后端生成调用支付宝 app 支付的签名订单信息,即为调起支付宝 app 支付的参数,详见 支付宝 App 支付请求参数说明(商户如果不使用支付宝支付方式,则可忽略该步骤);
  • 商户后端对调起小程序收银台的参数进行签名(参考 服务端签名),返回给商户前端;

商户前端(小程序)接入

  • 商户前端(小程序)调用 tt.pay 接口,调起小程序收银台,发起支付流程;
  • 商户前端(小程序)接收支付结果回调,进行后续业务处理

接入 DEMO

服务端接入

该服务端 DEMO 帮助开发者生成调用 tt.pay 接口的参数,通过参数 AppletVersion 来控制生成的结果,AppletVersion 为固定值 '3.0'

服务端 DEMO 生成订单信息 orderInfo 如下(参数值仅供参考):

{
    app_id: "800000040005",
    sign_type: "MD5",
    out_order_no: "MicroApp7075638135",
    merchant_id: "1300000004",
    timestamp: "1566720681",
    product_code: "pay",
    payment_type: "direct",
    total_amount: 1,
    trade_type: "H5",
    uid: "2019012211",
    version: "2.0",
    currency: "CNY",
    subject: "microapp test",
    body: "microapp test",
    trade_time: "1566720681",
    valid_time: "300",
    notify_url: "https://tp-pay.snssdk.com/cashdesk/test/paycallback",
    wx_url:
      "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx25161122572189727ea14cfd1832451500&package=2746219290",
    wx_type: "MWEB",
    alipay_url:
      "alipay_sdk=alipay-sdk-java-3.4.27.ALL&app_id=2018061460417275&biz_content=%7B%22body%22%3A%22%E6%B5%8B%E8%AF%95%E8%AE%A2%E5%8D%95%22%2C%22extend_params%22%3A%7B%7D%2C%22out_trade_no%22%3A%2211908250000028453790%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22seller_id%22%3A%222088721387102560%22%2C%22subject%22%3A%22%E6%B5%8B%E8%AF%95%E8%AE%A2%E5%8D%95%22%2C%22timeout_express%22%3A%22599m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay&notify_url=http%3A%2F%2Fapi-test-pcs.snssdk.com%2Fgateway%2Fpayment%2Fcallback%2Falipay%2Fnotify%2Fpay&sign=D2A6ua51os2aIzIH907ppK7Bd9Q2Kk5h7AtKPdudP%2Be%2BNTtAkp0Lfojtgl4BMOIQ3Z7cWyYMx6nk4qbntSx7aZnBhWAcImLbVVr1cmaYAedmrmJG%2B3f8G5TfAZu53ESzUgk02%2FhU1XV0iXRyE8TdEJ97ufmxwsUEc7K0EvwEFDIBCJg73meQtyCRFgCqYRWvmxetQgL7pwfKXpFXjAYsvFrRBas2YGYt689XpBS321g%2BZ8SZ0JOtLPWqhROzEs3dnAtWBW15y3NzRiSNi5rPzah4cWd4SgT0LZHmNf3eDQEHEcPmofoWfnA4ao75JmP95aLUxerMumzo9OwqhiYOUw%3D%3D&sign_type=RSA2&timestamp=2019-08-25+16%3A11%3A22&version=1.0",
    sign: "15aa99cd80878661a4d442b7540bdf96",
    risk_info: '{"ip":"127.0.0.1","device_id":"485737374363263"}'
}

服务端 DEMO 提供 Go、Java、Node 语言版本:

前端(小程序)接入

参考 tt.pay

(1)下单

在使用前,请先在商户后端完成业务订单创建,然后调用 Server SDK (参考服务端接入)方法,生成调起小程序收银台的订单信息参数 orderInfo

{
    app_id: "800000040005",
    sign_type: "MD5",
    out_order_no: "xxxx",
    merchant_id: "1300000004",
    ...
}

商户前端拿到 orderInfo参数后,使用 tt.pay 发起支付流程

tt.pay({
    orderInfo: orderInfo,
    ...
})

支付下单前的建议:

如果开发者没有自己的账号体系,请在调用 tt.pay 前调用 tt.login 并处于已登录状态,以避免用户处于未登录状态时支付订单,在登录后无法关联订单与登录后的账户

(2)查询微信支付结果

由于开发者未将微信和支付宝的密钥交付给字节跳动,无法代为发起交易,所以从小程序发起支付跳转微信之后,微信支付订单可能处于支付成功,取消等状态;此时需要商户前端实现 getOrderStatus 方法,用于在商户侧查询订单的支付状态,getOrderStatus 需开发者自行实现

tt.pay({
    ...
    getOrderStatus(res) {
        let { out_order_no } = res;
        return new Promise(function (resolve, reject) {
            // 商户前端根据 out_order_no 请求商户后端,查询当前订单的支付状态
            tt.request({
                url: "<your-backend-url>",
                success(res) {
                    // 商户后端查询的订单支付状态,返回小程序收银台支付结果
                    resolve({ code: 0 | 1 | 2 | 3 | 9 });
                },
                fail(err) {
                    reject(err);
                }
            });
        });
    },
    ...
})

resolve 的参数为一个对象,其中 code 是一个 number:

  • 0:支付成功
  • 1:支付超时
  • 2:支付失败
  • 3:支付关闭
  • 9:订单状态未知

(3)支付结果

参考 tt.pay

支付结果返回后有以下两个建议:

  1. 由于字节跳动无法代为发起交易,因而准确的订单状态(成功,失败...etc)信息以商户在微信支付/支付宝的订单状态为准;在触发 tt.pay success 回调后,保险起见(例如支付宝已成功支付,但用户杀掉 app 导致回跳失败)商户前端可轮询商户服务端获取准确的微信支付/支付宝的订单状态
// 这只是一个轮询查单的示例,请根据实际情况实现轮询查单

tt.pay({
    ...
    success(res) {
        if (res.code == 0) {
            // 支付成功处理逻辑,只有res.code=0时,才表示支付成功
            // 但是最终状态要以商户后端结果为准
            let count = 0

            let timer = setTimeout(() => {
                // 自行选择轮询次数
                if (count > 3) {
                    clearTimeout(timer)
                    // 商户根据自身需求处理轮询完未成功的状态
                    return
                }

                // 商户前端根据 out_order_no 请求商户后端查询微信/支付宝支付订单状态
                tt.request({
                    url: "<your-backend-url>",
                    success(res) {
                        // 商户后端查询到的微信/支付宝订单状态
                    },
                    fail(err) {
                        // 处理请求失败
                    }
                });

                count++
            }, 500)
        }
    }
    ...
})
  1. 商户维护订单信息:在特定的支付场景中,为防止重复支付,商户服务端需使用数据库维护支付订单信息,以保证在用户在特殊场景(例如支付宝已成功支付,但用户杀掉 app 导致回跳失败)其订单无需再次支付
点击纠错