脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Ruby - Ruby on Rails在Ping ++ 平台实现支付

Ruby on Rails在Ping ++ 平台实现支付

2020-05-07 10:59脚本之家 Ruby

本文给大家分享的是使用Ruby on Rails在Ping ++ 平台实现支付功能的代码,非常的实用,有需要的小伙伴可以参考下。

本地数据库创建订单表。

建议包含以下字段,参考官方API( https://pingxx.com/document/api#api-c-new):

order_no:required

?
1
2
3
4
5
6
7
8
9
10
商户订单号,适配每个渠道对此参数的要求,必须在商户系统内唯一。
alipay: 1-64 位,
wx: 1-32 位,
bfb: 1-20 位,
upacp: 8-40 位,
yeepay_wap:1-50 位,
jdpay_wap:1-30 位,
cnp_u:8-20 位,
cnp_f:8-20 位,
推荐使用 8-20 位,要求数字或字母,不允许特殊字符

app[id]:required

?
1
支付使用的 app 对象的 id,请登陆管理平台查看。

subject:required

?
1
2
商品的标题,该参数最长为 32 个 Unicode 字符,
银联全渠道(upacp/upacp_wap)限制在 32 个字节。

body:required

?
1
2
商品的描述信息,该参数最长为 128 个 Unicode 字符,
yeepay_wap 对于该参数长度限制为 100 个 Unicode 字符。

channel:required

?
1
2
3
4
5
6
7
8
9
10
11
12
支付使用的第三方支付渠道(更多请参考api)
 alipay:支付宝手机支付
 alipay_wap:支付宝手机网页支付
 alipay_qr:支付宝扫码支付
 alipay_pc_direct:支付宝 PC 网页支付
 apple_pay:Apple Pay
 bfb:百度钱包移动快捷支付
 bfb_wap:百度钱包手机网页支付  
 wx:微信支付
 wx_pub:微信公众账号支付
 wx_pub_qr:微信公众账号扫码支付
 jdpay_wap:京东手机网页支付

amount: required

?
1
2
订单总金额, 单位为对应币种的最小货币单位,
例如:人民币为分(如订单总金额为 1 元,此处请填 100)。

client_ip: required

?
1
发起支付请求终端的 IP 地址,格式为 IPV4,如: 127.0.0.1。

      
以上是在ping++ 平台创建订单时需要的参数

以下是在ping++ 平台创建订单成功以及付款成功回调的参数

?
1
2
3
4
5
6
paid :支付状态,默认为false
refunded :退款状态,默认为false
time_paid :付款时间
time_refunded:退款时间
charge_no:返回的charge编号
transaction_no :交易号

步骤:

1.本地创建一条订单记录

 def create_order

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#获取参数 
#判断参数合法性
 
order = Order.new
#保存订单信息,注意subject以及body的长度
#生成订单号并保存
order_no = (Time.now.to_formatted_s(:number)).to_s
6.times{ order_no<<rand(10).to_s }
order.order_no = order_no
 
#获取ip并保存
order.client_ip = request.remote_ip
 
if order.save
 #返回成功信息
else
 render_failure(order.errors.messages.first[1][0])
end
end

2.执行支付

现在ping++ 平台创建一条记录
1.在order.rb文件中新建一个方法

?
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
def pay_url
 #获取api_key以及app_id
 Pingpp.api_key = PingPlusPlus.get_ping_settings["PING_API_KEY"]
 app_id = PingPlusPlus.get_ping_settings["PING_APP_ID"]
 #不同支付渠道的回调地址
 case self.channel
   when "alipay"
   extra = {
  }
   when "wx"
   extra = {
  }
  end
 #ping++平台新建一个订单
 begin
  charge = Pingpp::Charge.create(
    :order_no => self.order_no,
    :app  => { :id => app_id },
    :channel => self.channel,
    :amount => self.amount.round(2) * 100.to_i,
    :client_ip => self.client_ip,
    :currency => "cny",
    :subject => self.subject[0..31],
    :body  => self.body[0..127],
    :extra  => extra
    )
  
  return charge
 rescue Pingpp::PingppError => error
   logger.error 'ping++平台创建订单失败'
   logger.error error.http_body
   return false
 end
end

2.调用pay_url方法创建订单,返回给客户端charge对象,客户端拿着charge对象去ping++ 平台支付

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def confirm_and_payment
 order_no = params[:order_no]
 channel = params[:channel]
 if order_no.blank? || channel.blank?
  render_failure("参数不完整!") and return
 end
 
 order = Order.where(order_no: order_no).first
 if order.blank?
   render_failure("订单不存在!")and return
 end
 
 charge = order.pay_url
 if charge == false
  render_failure("订单支付失败!") and return
 else
  order.update_attribute(:charge_no ,(JSON.parse charge.to_s)['id'])
  render(:json => charge)
 end
end

异步通知更新付款结果

?
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def notify
 
 status = 400
 
 #判断请求是否有ping++的签名信息
 if request.headers['x-pingplusplus-signature'].blank?
  status = 401
  logger.debug '【报哪家】:======付款回调请求来源错误!!!!!'
  return
 end
 
 #获取签名信息
 raw_data = request.body.read
 if request.headers['x-pingplusplus-signature'].is_a?(Array)
  signature = request.headers['x-pingplusplus-signature'][0].to_s
 else
  signature = request.headers['x-pingplusplus-signature'].to_s
 end
 
 # 获取「Webhooks 验证 Ping++ 公钥」
 pub_key_path ="#{Rails.root}/config/rsa_public_key.pem"
 if verify_signature(raw_data, signature, pub_key_path)
   #处理接收的结果
   event = JSON.parse(raw_data)
   #付款成功
   if event["type"] == 'charge.succeeded'
 
   # 开发者在此处加入对支付异步通知的处理代码
   order_no = event['data']['object']['order_no']
   order = Order.where(order_no: order_no).first
   order_from = order.status
   if order.present?
    #更新字段
    order.paid = event['data']['object']['paid']
    if order.save
      status = 200
    else
     status = 500
    end
   else
     logger.debug '数据库没有该条记录!'
   end
 
   #退款成功
  elsif event['type'] == 'refund.succeeded'
 
    # 开发者在此处加入对退款异步通知的处理代码
   order_no = event['data']['object']['order_no']
   order = Order.where(order_no: order_no).first
   if order.present?
    #更新字段
    order.time_refunded = Time.at(event['data']['object']['time_succeed'])
    if order.save
     status = 200
    else
     status = 500
    end
   else
     logger.debug '数据库没有该条记录!'
   end
 
  else
   logger.debug '付款回调返回未知操作!'
  end
 
  else
   logger.debug '付款回调请求来源错误!'
   status = 403
  end
  render :nothing => true, :status => status
end

延伸 · 阅读

精彩推荐
  • Ruby剖析 Ruby 访问控制

    剖析 Ruby 访问控制

    前面,我们说 Ruby 没有函数,只有方法.而且实际上有不止一种方法.这一节我们介绍 访问控制 (accesscontrols). 想想当我们在最高层而不是在一个类的定义里定义...

    ruby教程网3572020-04-08
  • RubyRuby环境下安装使用bundler来管理多版本的gem

    Ruby环境下安装使用bundler来管理多版本的gem

    这篇文章主要介绍了Ruby环境下安装使用bundler来管理多版本的gem的方法,举了Ruby On Rails中的应用实例来进行演示,需要的朋友可以参考下 ...

    日拱一卒4332020-05-10
  • RubyRuby进行文件信息输出实例代码

    Ruby进行文件信息输出实例代码

    Ruby进行文件信息输出实例代码,数据是随机的,所以每次的记录都会不同。 ...

    ruby教程网2962020-04-10
  • RubyRuby简洁学习笔记(一):字符串、数字、类和对象

    Ruby简洁学习笔记(一):字符串、数字、类和对象

    这篇文章主要介绍了Ruby简洁学习笔记(一):字符串、数字、类和对象,本文是学习笔记第一篇,需要的朋友可以参考下 ...

    脚本之家2472020-04-20
  • Ruby简要说明Ruby中的迭代器

    简要说明Ruby中的迭代器

    这篇文章主要介绍了Ruby中的迭代器,迭代器的概念在动态语言的编程中十分重要,文章中介绍了Ruby中的each迭代器和collect迭代器,需要的朋友可以参考下 ...

    goldensun2772020-04-25
  • RubyRuby设计模式编程中使用Builder建造者模式的实例

    Ruby设计模式编程中使用Builder建造者模式的实例

    这篇文章主要介绍了Ruby设计模式编程中使用Builder建造者模式的实例,建造者模式将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表...

    范孝鹏2192020-05-07
  • RubyRuby迭代器的7种技巧分享

    Ruby迭代器的7种技巧分享

    这篇文章主要介绍了Ruby迭代器的7种技巧分享,Ruby中的迭代器非常人性化,本文既是讲解了7个技巧也是讲解了7种迭代器,需要的朋友可以参考下 ...

    脚本之家4782020-04-20
  • RubyCentOS中配置Ruby on Rails环境

    CentOS中配置Ruby on Rails环境

    经过一个上午的折腾,终于把ROR环境在CentOS中搞定,绕了很多弯路,把文章写下来总结一下 ...

    可乐加糖4762020-04-12