本文将介绍如何使用小程序Serverless云调用开发一个具有花呗支付能力的小程序。

准备工作

在开始前,确保您已经完成以下准备工作:
  • 注册支付宝企业开发者账号。

    如果您尚未注册支付宝小程序账号,使用支付宝账号登录蚂蚁金服开放平台,并完成企业开发者身份注册。详细信息,请参见开发者入驻说明

  • 下载并安装支付宝小程序开发者工具。

    详细信息,请参见下载说明

  • 已安装 nodejs开发环境。

步骤一:开通小程序云服务

  1. 登录小程序云控制台
  2. 云产品开通页面,单击《小程序云服务协议》链接。小程序云服务开通
  3. 在阅读后,勾选我已阅读并同意《小程序云服务协议》复选框,然后单击立即开通

步骤二:创建服务空间

小程序开发中创建的云资源会和服务空间进行关联。每个服务空间都有一个全局唯一的space ID。在使用云资源时,都通过这个space ID进行关联。参考以下步骤,创建服务空间并设置数据库权限:

  1. 小程序云控制台的左侧导航栏,单击小程序Serverless > 服务空间管理
  2. 单击创建服务空间,输入服务空间名称,然后单击确定
  3. 创建成功后,单击详情查看space ID、secret和endpoint信息。
  4. 单击小程序Serverless > 云数据库,然后在页面右上角选择已创建的服务空间。
  5. 单击修改数据库权限,将write权限修改为true
    说明 为了保证数据安全,默认数据库访问受限。您需要根据需要设置数据库权限,更多详细信息,请参见数据权限管理

步骤三:开通扩展能力

  1. 小程序云控制台的左侧导航栏,选择小程序Serverless > 扩展能力
  2. 扩展能力页面,单击立即开通
  3. 在弹出的对话框,单击前往RAM进行授权,然后单击同意授权允许小程序访问函数计算服务。
  4. 返回扩展能力页面,查看开通状态。

步骤四:创建支付宝小程序应用

参考以下步骤,在蚂蚁金服开放平台创建支付宝小程序:

  1. 使用支付宝账号登录蚂蚁金服开放平台进入开发者中心。
  2. 选择小程序应用,然后单击创建应用并根据引导创建一个小程序应用。
  3. 在左侧导航栏单击设置
  4. 单击开发设置,在开发信息下的接口加签方式区域配置支付宝公钥。

    您可以通过RSA密钥生成工具一键生成小程序密钥。接口加签方式有普通公钥和证书公钥两种,主要用于签名和验证。其中私钥由开发者保存,公钥可对外公开,私钥用于签名,公钥用于验证签名。开发者需要保存自己的私钥,通过支付宝提供的公钥进行通信来保证信息传输的完整性以及发送者身份的真实性。详细信息,请参见生成支付宝RSA密钥

    注意 企业开发者若涉及资金类支出接口接入,必须使用公钥证书模式。
  5. 在小程序详情开发管理页面的功能列表中,单击右上角添加功能按钮,添加小程序支付
    小程序支付功能需要签约才能生效,在小程序上线后,单击功能列表右侧签约。签约完成后,需要1个工作日左右的审批时间(审批结果会以短信和邮件形式告知),审批成功后,功能状态会变为已生效

步骤五:添加支付宝小程序

在开发前,您需要将支付宝小程序信息添加到阿里云小程序Serverless控制台。

完成以下操作,添加支付宝小程序信息:

  1. 登录小程序云控制台
  2. 左侧导航栏,单击小程序Serverless > 设置
  3. 单击支付宝页签,然后单击添加
  4. 输入您的私钥,即步骤四中生成的小程序RSA私钥。
  5. 输入支付宝公钥,支付宝公钥从蚂蚁金服开放平台->开发中心->设置->开发设置->开发信息中的接口加签方式中查看获取。

步骤六:获取模板代码

  1. 打开小程序开发者工具,在首页小程序模板的开放能力分类中选择花呗支付模板。
  2. 单击下一步,设置项目名称和项目路径,完成项目创建。

步骤七:快速体验

  1. 在小程序开发者工具中登录支付宝开发者账号,然后关联对应的小程序。
  2. client/pages/app.js中对应的如下小程序配置项改为用户自己的参数。
    appId: '2021*********', // 小程序应用标识
    spaceId: 'ca8eb10f-26c1-4bee-**********', // 服务空间标识
    clientSecret: 'Xckz2************', // 服务空间 secret key
    endpoint: 'https://api.************' // 服务空间地址,从小程序Serverless控制台处获得 	
    appId即在小程序Serverless中设置的AppId,spaceId、clientSecret、endpoint参数请查看小程序云服务空间详情,请参考步骤二。
    保存文件后,打开IDE的真机调试,就可以在您的手机支付宝上使用小程序进行花呗支付。至此,我们已经完成了一个简单的花呗支付小程序的搭建,并将最核心的能力使用小程序Serverless开发完成。

小程序云Serverless代码详解

  • 初始化Serverless SDK

    在使用小程序Serverless服务前,需要您在小程序中安装小程序Serverless客户端SDK并初始化。小程序Serverless客户端SDK的更多信息请参见安装客户端SDK2.2版本

    // client/app.js
    import MPServerless from '@alicloud/mpserverless-sdk';
    
    const mpserverless = new MPServerless({
      uploadFile: my.uploadFile,
      request: my.request,
      getAuthCode: my.getAuthCode,
    }, {
      appId: ' ', // 小程序应用标识
      spaceId: ' ', // 服务空间标识
      clientSecret: ' ', // 服务空间 secret key
      endpoint: ' ' // 服务空间地址,从小程序Serverless控制台处获得
    });	
  • 初始化云调用SDK并授权登录

    要使用小程序云提供的扩展能力,您需要先在控制台开通云调用功能,然后在小程序中安装云调用SDK并进行初始化。

    在调用小程序Serverless服务前,需要先调用authorize接口请求授权,支付宝小程序的授权请求参数authProvider应为alipay_openapi, 更多信息请参见authorize

    // client/app.js
    import cloud from 'alipay-serverless-sdk';
    
    cloud.init(my.serverless);
    App({
      async onLaunch(options) {
        var res = await my.serverless.user.authorize({
          authProvider: 'alipay_openapi',
        });
      },
    });
    					
  • 创建交易

    以下代码调用payment.common.create和cloud.payment.huabei.create接口实现了创建直接付款订单和花呗分期付款交易能力,更多直接付款和花呗分期接口信息请参见payment.common.createpayment.huabei.create

    async tradeCreate() {
        let createRes
        if (this.data.checked === '1') {
          // 直接付款
          createRes = await cloud.payment.common.create('小程序Serverless支付测试', "demo" + new Date().getTime(), '0.03', this.data.userId);
        } else {
          // 花呗分期
          var huabeiConfig = new Object({
            hbFqNum: "3",
            hbFqSellerPercent: "100"
          });
          createRes = await cloud.payment.huabei.create('小程序Serverless支付测试', "demo" + new Date().getTime(), '0.03', this.data.userId, huabeiConfig);
        }
        this.setData({
          tradeNO: createRes.tradeNo,
          outTradeNo: createRes.outTradeNo
        })
        return createRes.tradeNo
      },
  • 付款

    以下代码调用my.tradePay支付宝开放能力API唤起支付宝收银台进行支付,更多小程序支付信息请参见小程序支付

    async onRepeatPayHandler(data) {
        my.tradePay({
          tradeNO: this.data.tradeNO,
          success: async (res) => {
            if (res.resultCode === "9000") {
              my.alert({
                title: '支付成功',
                content: res.resultCode,
              });
              const value = data.currentTarget.dataset.item
              const { key } = value
              const { paymentHistory } = this.data
              paymentHistory.map(v => {
                if (v.key === key) {
                  v.tradeStatus = 'TRADE_SUCCESS'
                }
              })
              my.serverless.db.collection('payment').updateOne({
                key
              }, {
                $set: {
                  tradeStatus: 'TRADE_SUCCESS'
                }
              })
              this.setData({
                paymentHistory
              })
            }
          },
        });
      },
  • 退款

    以下代码调用payment.common.refund云调用接口进行退款操作,更多信息请参见payment.common.refund

    async onRefundPayHandler(data) {
        const value = data.currentTarget.dataset.item
        const { outTradeNo, totalAmount, key } = value
        const rs = await cloud.payment.common.refund(outTradeNo, String(totalAmount))
        if (rs.code === "10000") {
          my.showToast({
            content: '退款成功',
          });
          const { paymentHistory } = this.data
          paymentHistory.map(v => {
            if (v.key === key) {
              v.tradeStatus = 'TRADE_CLOSED'
            }
          })
          this.setData({
            paymentHistory
          })
          my.serverless.db.collection('payment').updateOne({
            key
          }, {
            $set: {
              tradeStatus: 'TRADE_CLOSED'
            }
          })
        } else {
          my.showToast({
            content: '退款失败',
          });
        }
        console.log(rs)
      },