使用ruby实现支付宝APP支付全流程

本文介绍如何使用Ruby实现支付宝APP支付功能,包括创建应用、配置回调地址、获取支付参数及处理支付回调等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发前提
首先需要在支付宝开放平台创建一个应用并申请APP支付权限。
然后补全开发信息,支付宝APP支付的回调地址需要在开放平台配置。
重点:
接口加签方式 - 我选择的是普通公钥方式;
下载支付宝开放平台开发助手工具,我选择的是RSA2加密方式,一键生成 应用私钥和应用公钥,好好保存下来;
然后将生成的应用公钥填入到接口加签方式的弹出的框内,以获取支付宝公钥。
一切准备就绪,开始接入支付宝APP支付:

进入正题
在实现支付宝APP支付时,后端只需要做两步操作:
1.将发起支付用到的参数返回给APP原生,且数据库保存预支付订单信息;
2.支付回调,支付宝APP支付完成后请求一个回调地址,这个回调地址是在 第1步获取支付参数时 填写的,验证参数后,更改数据库保存的订单支付状态;

首先是第一步:获取APP调起支付宝支付用的参数

#获取APP调起支付用的参数
def get_alipay_datas
  #商户订单号
  out_trade_no = "#{Time.now.strftime('%Y%m%d%H%M%S')}#{rand(1...999999)}"
  biz_content = {
    out_trade_no: out_trade_no, # 商户订单号
    product_code: 'QUICK_MSECURITY_PAY', #固定
    total_amount: 0.01, # 实际支付金额,单位为元,精确到小数点后两位
    subject: "商品1" #订单标题
  }
  datas = {
    app_id: ENV['ALIPAY_APPID'], # 支付宝分配给开发者的应用ID
    method: 'alipay.trade.app.pay', # 接口名称,固定
    format: 'json',
    charset: 'utf-8',
    sign_type: 'RSA2', # 商户生成签名字符串所使用的签名算法类型,目前支持RSA2和RSA
    timestamp: Time.now.strftime("%Y-%m-%d %H:%M:%S"), # 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss"
    version: '1.0', #调用的接口版本,固定为:1.0
    biz_content: JSON.generate(biz_content),
    notify_url: ENV['ALIPAY_NOTIFY_URL'] #回调地址
  }
  datas.store("sign", get_alipay_sign_str(datas)) #通过以上参数生成sign
  datas.delete(:app_id) #删除敏感的app_id,让前端手动拼接
  datas = sort_param(datas).handle{ |key,value|
    {
      "#{CGI::escape(key.to_s)}".to_sym => "#{CGI::escape characet(value.to_s)}"
    }
  }
  datas #这个结果便是APP调起支付需要的参数了
  #此时便可以创建数据库预支付的订单信息了,完成内部程序逻辑
end

#获取支付宝支付sign
def get_alipay_sign_str params
  sign_arr = []
  sort_param(params).map{ |key,value|
    sign_arr << "#{key}=#{characet(value)}" if value.present? #排除为空的值
  }
  sign_str = sign_arr.join('&') #参数以&符拼接成字符串
  #读取生成的私钥文件
  key = File.read(File.dirname(__FILE__) + '/alipay/rsa.pem') #读取应用私钥文件,即通过支付宝开放平台开发助手工具生成的应用私钥
  pkey = OpenSSL::PKey::RSA.new(Base64.decode64(key))
  signature = pkey.sign('sha256', sign_str)
  Base64.strict_encode64(signature)
end

#hash排序
def sort_param(data)
  data = data.sort{ |a,b| a.to_s <=> b.to_s }.to_h
end

然后就是第二步:支付回调
这个地址就是第一步的 获取APP调起支付宝支付用的参数传入的notify_url参数,也是访问如下代码方法的链接地址;

desc '支付宝支付回调'
post :alipay_notify_url do
  ActiveRecord::Base.transaction do
    $logger.info "支付宝支付回调"
    params_data = params
    if params_data[:trade_status].present? && (params_data[:trade_status] == 'TRADE_SUCCESS' || params_data[:trade_status] == 'TRADE_FINISHED') #支付宝回调参数正确
      #支付完成
      if Redis.is_pay_order_vaild? params_data[:out_trade_no] #判断redis此订单号是否存在,且状态是否为未回调 才可以进行回调操作
        $logger.info "通过redis验证"
        #验签过程
        if check_alipay(params_data)
          #验签成功
          #更新此订单的redis数据
          Redis.set_pay_order_invaild params_data[:out_trade_no]
          $logger.info "验签成功-订单号#{params_data[:out_trade_no]}"
          #判断APPID是否正确/订单号是否存在/订单未支付状态/是否为支付宝支付/判断金额是否正确
          pay_order = Order.find_by_out_trade_no(params_data[:out_trade_no]) #预支付订单信息
          if params_data[:app_id] == ENV['ALIPAY_APPID'] && pay_order.present? && !pay_order.is_paid? && pay_order.pay_type == 'alipay' && pay_order.spend_rmb_money.to_d == params_data[:total_amount].to_d
            #回调信息通过
            $logger.info "回调信息通过-订单号#{params_data[:out_trade_no]}"
            #开始执行内部程序逻辑处理,如修改订单状态
            xxxxxxxx
            #逻辑处理已完成
            $logger.info "逻辑处理已完成-订单号#{params_data[:out_trade_no]}"
          else
            $logger.info "回调信息未通过-订单号#{params_data[:out_trade_no]}"
          end
        else
          $logger.info "验签失败-订单号#{params_data[:out_trade_no]}"
        end
      end
    end
  end
end

#支付宝支付回调验签
def check_alipay params
  sign = params[:sign] #将传入的sign保存下来
  params.delete(:sign) #删除sign参数,保存其余参数
  params.delete(:sign_type) #删除sign_type参数,保存其余参数
  sign_arr = []
  #params = params.each{ |key, val| params[key] = CGI::unescape(val) }
  sort_param(params).map{ |key,value|
      sign_arr << "#{key}=#{CGI::unescape(value)}"
  }
  sign_str = sign_arr.join('&') #参数以&符拼接成字符串
  signature = Base64.strict_decode64(sign)
  key = File.read(File.dirname(__FILE__) + '/alipay/rsa.key') #注意!!!此时用到的公钥文件,不是通过支付宝开放平台开发助手工具生成的应用公钥,而是在开放平台-接口加签方式-通过应用公钥获取的支付宝公钥
  pkey = OpenSSL::PKey::RSA.new(Base64.decode64(key))
  pkey.verify('sha256', signature, sign_str) #完成加密
end

以上便是 ruby实现支付宝APP支付全流程啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值