Ruby on RailsでPing ++プラットフォームでの決済を実現
2022-02-01 10:22:36
注文テーブルを作成するためのローカルデータベース。
公式APIを参考に、以下のフィールドを含めることが推奨されています( https://pingxx.com/document/api#api-c-new ).
注文番号:必須
Merchant order number, adapted to the requirements of each channel for this parameter, must be unique in the merchant system.
alipay: 1-64 bits.
wx: 1-32 bits.
bfb: 1-20 bits.
upacp: 8-40 bits.
yeepay_wap: 1-50 bits.
jdpay_wap:1-30 bits.
cnp_u:8-20 bits.
cnp_f:8-20 bits.
Recommended 8-20 bits, requires numbers or letters, no special characters allowed
app[id]:必須
The id of the app object used for payment, please login to the admin panel to see it.
件名:必須
The title of the product, this parameter is limited to a maximum of 32 Unicode characters.
UnionPay Omnichannel (upacp/upacp_wap) is limited to 32 bytes.
本文:必須
The description of the product, the maximum length of this parameter is 128 Unicode characters.
yeepay_wap is limited to 100 Unicode characters for this parameter.
チャンネル:必須
Third-party payment channels used for payment (please refer to api for more)
alipay:Alipay mobile payment
alipay_wap:Alipay mobile web payment
alipay_qr:Alipay sweep code payment
alipay_pc_direct:Alipay PC web payment
apple_pay:Apple Pay
bfb:Baidu Wallet Mobile Quick Payment
bfb_wap:Baidu Wallet Mobile Web Payment
wx:微信支付
wx_pub:微信公众账号支付
wx_pub_qr:微信公众账号扫码支付
jdpay_wap:京东手机網頁支付
amount: 必須
The total amount of the order, in the smallest currency unit of the corresponding currency.
For example, RMB is cents (if the total amount of the order is 1 yuan, enter 100 here).
client_ip: 必須
The IP address of the endpoint initiating the payment request, in IPV4 format, e.g. 127.0.0.1.
ping++プラットフォームで注文を作成するために必要なパラメータは、以下のとおりです。
ping++プラットフォームで注文を正常に作成し、支払いコールバックを正常に行うには、以下のパラメータが必要です。
paid : Payment status, default is false
refunded : refund status, default is false
time_paid : time of payment
time_refunded : refunded time
charge_no: the charge number returned
transaction_no : transaction number
ステップ
1. ローカルでオーダーレコードを作成する
def create_order
#Get the parameters
#Determine the legitimacy of the parameter
order = Order.new
#Save the order information, note the subject and the length of the body
#Generate order number and save it
order_no = (Time.now.to_formatted_s(:number)).to_s
6.times{ order_no<<rand(10).to_s }
order.order_no = order_no
# Get the ip and save it
order.client_ip = request.remote_ip
if order.save
# return success message
else
render_failure(order.errors.messages.first[1][0])
end
end
2. 決済の実行
ここで、ping++プラットフォームは、レコードを作成します。
1. order.rb ファイルに新しいメソッドを作成します。
def pay_url
# Get api_key and app_id
Pingpp.api_key = PingPlusPlus.get_ping_settings["PING_API_KEY"]
app_id = PingPlusPlus.get_ping_settings["PING_APP_ID"]
# callback address for different payment channels
case self.channel
when "alipay"
extra = {
}
when "wx"
extra = {
}
end
#ping++ platform to create a new order
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++ platform failed to create order'
logger.error error.http_body
return false
end
end
2. pay_urlメソッドを呼び出して注文を作成し、chargeオブジェクトをクライアントに返し、クライアントはchargeオブジェクトをping++プラットフォームに持って行って支払います。
def confirm_and_payment
order_no = params[:order_no]
channel = params[:channel]
if order_no.blank? || channel.blank?
render_failure("Parameter incomplete! ") and return
end
order = Order.where(order_no: order_no).first
if order.blank?
render_failure("Order does not exist! ") and return
end
charge = order.pay_url
if charge == false
render_failure("Order payment failed! ") and return
else
order.update_attribute(:charge_no ,(JSON.parse charge.to_s)['id'])
render(:json => charge)
end
end
決済結果更新のための非同期通知
def notify
status = 400
# Determine if the request has the ping++ signature information
if request.headers['x-pingplusplus-signature'].blank?
status = 401
logger.debug '[report which]: ====== payment callback request source error !!!!!'
return
end
# Get signature information
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
# Get "Webhooks verify Ping++ public key"
pub_key_path = "#{Rails.root}/config/rsa_public_key.pem"
if verify_signature(raw_data, signature, pub_key_path)
# Process the received result
event = JSON.parse(raw_data)
#Payment success
if event["type"] == 'charge.succeeded'
# The developer adds code to handle asynchronous notifications for payments here
order_no = event['data']['object']['order_no']
order = Order.where(order_no: order_no).first
order_from = order.status
if order.present?
# update field
order.paid = event['data']['object']['paid']
if order.saved
status = 200
else
status = 500
end
else
logger.debug 'The database does not have this record!
end
# Refunds are successful
elsif event['type'] == 'refund.refunded'
# The developer adds code to handle asynchronous notifications of refunds here
order_no = event['data']['object']['order_no']
order = Order.where(order_no: order_no).first
if order.present?
# update field
order.time_refunded = time.at(event['data']['object']['time_succeed'])
if order.save
status = 200
else
status = 500
end
else
logger.debug 'The database does not have this record!
end
else
logger.debug 'The payment callback returned an unknown operation!
end
else
logger.debug 'The payment callback request came from an incorrect source!
status = 403
end
render :nothing => true, :status => status
end
関連
-
Rubyの二分探索(dichotomous search)アルゴリズムの簡単な例
-
基本的なユーザー登録とログイン機能を実装するためのRuby on Railsチュートリアル
-
Rubyオブジェクト指向プログラミングにおけるクラスメソッドとクラスエクステンション
-
UbuntuでRuby on RailsフレームワークとRubyMine IDEを設定する
-
アプレットを置き換えるHTMLスクリプトを記述するRubyの例
-
Rubyのgemパッケージ管理およびgemソース構築のチュートリアル
-
Rubyのデザインパターンプログラミングにおけるコマンドパターンの活用を徹底分析
-
Rubyのデザインパターン。プログラミングにおけるストラテジーパターンの活用
-
Rubyの4つの比較関数(equal?, eql?, ==, ===)について解説します。
-
Rubyのバージョンを管理するためのrbenvの使い方
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ruby on railsのモデルアソシエーションについて解説
-
MongoDBに接続するためのRuby on Railsフレームワークアプリケーション チュートリアル
-
RubyのProcクラスとProc.newメソッドの使用法
-
Ruby on Railsで構築するアプリケーションの基本的なディレクトリ構造のまとめ
-
Ruby on Railsのjquery_ujsコンポーネントが遅くなる問題が解決された
-
RubyインタプリタをOSにインストールするためのチュートリアル
-
Ruby on RailsでMarkdownを使用する方法
-
Rubyにおけるrequireの使用例
-
Ruby on Railsのマイグレーションに関するいくつかの考慮点
-
Rubyプログラミングにおけるネーミングスタイルガイド