Create an order table from the local database.
It is recommended to include the following fields. Refer to the official API( https://pingxx.com/document/api#api -c-new):
order_no:required
1
2
3
4
5
6
7
8
9
10
|
The merchant order number, which adapts 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 digits, Upacp: 8-40 bits, yeepay_ WAP: 1-50 bits, jdpay_ WAP: 1-30 bits, cnp_ u: 8-20 digits, cnp_ f: 8-20 digits, It is recommended to use 8-20 digits. Numbers or letters are required. Special characters are not allowed |
app[id]:required
1
|
Please log in to the management platform to view the ID of the app object used for payment. |
subject:required
1
2
|
The title of the item. The maximum length of this parameter is 32 Unicode characters, UnionPay Omni channel (upacp / upacp_wap) is limited to 32 bytes. |
body:required
1
2
|
Description information of the product. The maximum length of this parameter is 128 Unicode characters, yeepay_ WAP is limited to 100 Unicode characters for this parameter. |
channel:required
1
2
3
4
5
6
7
8
9
10
11
12
|
Third party payment channels used for payment (please refer to API for more information) Alipay: Alipay mobile phone payment alipay_ Wap: Alipay mobile phone web payment alipay_ Qr: Alipay sweep code payment alipay_ pc_ Direct: Alipay PC web payment apple_pay:Apple Pay BFB: Baidu wallet mobile express payment bfb_ WAP: Baidu wallet mobile web payment Wx: wechat payment wx_ Pub: wechat public account payment wx_ pub_ QR: wechat public account code scanning payment jdpay_ WAP: JD mobile web payment |
amount: required
1
2
|
The total amount of the order. The unit is the minimum currency unit of the corresponding currency, For example: RMB is cents (if the total amount of the order is 1 yuan, please fill in 100 here). |
client_ip: required
1
|
The IP address of the terminal initiating the payment request, in the format of IPv4, such as 127.0.0.1. |
The above parameters are required when creating an order on the Ping + + platform
The following are the parameters for successful order creation and payment callback on Ping + + platform
1
2
3
4
5
6
|
Pay: payment status, which is false by default Refunded: refund status, which is false by default time_ Pay: payment time time_ Refunded: refund time charge_ No: returned charge number transaction_ No: transaction number |
Steps:
1. Create an order record locally
def create_order
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#Get parameters #Judge the validity of parameters order = Order. new #Save the order information and pay attention to the length of subject and body #Generate order number and save order_no = ( Time .now.to_formatted_s( :number )).to_s 6 .times{ order_no<<rand( 10 ).to_s } order.order_no = order_no #Get IP and save order.client_ip = request.remote_ip if order.save #Return success information else render_failure(order.errors.messages.first[ 1 ][ 0 ]) end end |
2. Execution of payment
Now Ping + + platform creates a record
1. In order Create a new method in Rb file
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 #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 of different payment channels case self .channel when "alipay" extra = { } when "wx" extra = { } end #Ping + + platform creates 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. Call pay_ The URL method creates an order and returns it to the client charge object. The client takes the charge object to Ping + + platform for payment
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( "Incomplete parameters!" ) 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 |
Update payment results asynchronously
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 #Judge whether the request has the signature information of Ping + + if request.headers[ 'x-pingplusplus-signature' ].blank? status = 401 logger.debug '[to whom]: = = = = = 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 verification Ping + + public key" if verify_signature(raw_data, signature, pub_key_path) #Process received results event = JSON .parse(raw_data) #Payment succeeded if event[ "type" ] == 'charge.succeeded' #Developers add the processing code for asynchronous payment notification 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.save status = 200 else status = 500 end else logger.debug 'There is no such record in the database! ' end #Refund successful elsif event[ 'type' ] == 'refund.succeeded' #Developers add the processing code of asynchronous refund notification 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 'There is no such record in the database! ' end else logger.debug 'unknown operation returned from payment callback!' end else logger.debug 'payment callback request source error!' status = 403 end render :nothing => true , :status => status end |