支付宝扫码支付流程

    payment

  1. 准备工作
  2. 新建应用
  3. 相关接口
  4. 流程调用
  5. 相关实现(golang)

准备工作

  1. 证书准备
    关于如何制作证书可以参考官网OpenSSL工具介绍.直接用工具生成可以参考这里。生成的公钥需提供给支付宝账号管理者上传到支付宝开放平台,私钥需填写到代码中供签名时使用。

  2. 支付宝提供了相应的开发测试功能,你可以点击”开发者中心”–>”研发服务”–>”沙箱”.这里给你提供了相应的app key等相关信,使用沙箱做开发测试再好不过了。

新建应用

我当前的项目为”网页移动应用”类型,新建应用地址。新建应用的相关证件请自己准备。

相关接口

  1. 支付相关接口
  2. 支付回调接口(新建应用的时候需要提供的回调地址),内网测试可以使用frp做调试。

流程调用

  1. 客户端调用服务器api,生成对应的系统order并提交对应的order信息到alipay系统,设置订单付款成功回调地址。
  2. 服务器端根据提交的订单获取alipay返回的付款地址.
  3. 客户端扫描根据地址生成的二维码进行付款,付款成功以后alipay将会调用服务器端提交订单时设置的回调地址,通知服务器端付款状态

相关实现(golang)

  • 包引用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import (
    "fmt"
    "net/http"
    "time"

    "git.coding.net/ydxxm-server/models"
    "git.coding.net/ydxxm-server/pkg"
    "git.coding.net/ydxxm-server/pkg/constants"
    "git.coding.net/ydxxm-server/pkg/domain"
    "git.coding.net/ydxxm-server/services"
    alipay2 "git.coding.net/ydxxm-server/thirdparty/alipay"
    "git.coding.net/ydxxm-server/tool"
    "git.coding.net/ydxxm-server/tool/validate"
    "github.com/smartwalle/alipay"
    )
  • 订单接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // @Title Pay pay of alipay
    // @Description Pay pay of alipay
    // @Param order body domain.OrderDomain true "order"
    // @Success 200 {string} pay success
    // @router /pay [post]
    func (a *AlipayController) Pay() {
    order := &domain.OrderDomain{}
    a.ErrorHandler(a.Unmarshal(order))
    a.ErrorHandler(validate.ValidatorExtend(order), http.StatusBadRequest)
    order.TradeNo = tool.TradeNo(time.Now())

    product := &models.Product{Id: order.ProductId}
    err := productService.Read(product)
    a.ErrorHandler(err, http.StatusUnprocessableEntity, constants.ProductNotFound)

    order.Price = product.Price
    client := alipay2.NewAlipayClient()
    p := alipay.AliPayTradeWapPay{}
    p.NotifyURL = tool.Joint(pkg.SingleLoader.Get("domain"), "/api/alipay/notify")
    p.Subject = order.Title
    p.OutTradeNo = order.TradeNo
    p.TotalAmount = order.Summation()
    p.ProductCode = constants.PRODUCT_CODE

    url, err := client.Client.TradeWapPay(p)
    a.ErrorHandler(err, http.StatusUnprocessableEntity)

    a.ErrorHandler(a.addOrder(order, product), http.StatusUnprocessableEntity)
    a.JsonData(domain.PayInfo{URL: url.String(), TradeNo: order.TradeNo})
    }
  • 订单提交后回调接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    // @Title Notify alipay auth notify url
    // @Description Notify alipay auth notify url
    // @Success 200 {string} logout success
    // @router /notify [post]
    func (a *AlipayController) Notify() {
    tradeNo := a.GetString("trade_no")
    outTradeNo := a.GetString("out_trade_no")
    amount, _ := a.GetFloat("total_amount")
    buyerId := a.GetString("buyer_id")
    order := &models.Order{TradeNo: outTradeNo}
    err := orderService.Read(order, "trade_no")
    if err != nil || !order.Validate(float32(amount)) {
    a.ErrorHandler(err, http.StatusUnprocessableEntity, constants.OrderInvalid)
    return
    }

    order.PayStatus = constants.Finished
    order.Status = constants.OrderPlaying
    order.OutTradeNo = tradeNo
    order.Account = buyerId

    history := &models.WalletHistory{
    Money: order.Summation(),
    WalletType: constants.AliPay,
    ActionType: constants.Expense,
    Account: order.Account,
    }

    err = orderService.Update(order)
    if err != nil {
    // 添加操作日志
    history.Description = fmt.Sprintf(constants.PayFailedInfo, order.Account, constants.Alipay, time.Now(), amount, err.Error())
    walletHistoryService.Create(history)
    // 退款操作
    alipay2.NewAlipayClient().Client.TradeRefund(alipay.AliPayTradeRefund{TradeNo: order.TradeNo})
    a.refund(order)
    return
    }

    history.Description = fmt.Sprintf(constants.AlipayConsumeInfo, order.Account, time.Now().Format(constants.DateYMDHM), order.Summation())
    walletHistoryService.Create(history)

    a.JsonData(map[string]string{})
    }
page PV:  ・  site PV:  ・  site UV: