1. Create application and sandbox environment
Sandbox application: https://openhome.alipay.com/platform/appDaily.htm?tab=info
Code scanning registration
Sandbox account number: https://openhome.alipay.com/platform/appDaily.htm?tab=account
The quota can be modified
2. Alipay development documentation
Document home page: https://openhome.alipay.com/developmentDocument.htm
Introduction to computer website payment products: https://docs.open.alipay.com/270
Quick access to computer website payment: https://docs.open.alipay.com/270/105899/
API list: https://docs.open.alipay.com/270/105900/
SDK documentation: https://docs.open.alipay.com/270/106291/
Python Alipay SDK: https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
3. Payment process of computer website
4. Configure RSA2 public-private key
Tips:
Mido mall private key encrypts data, and Mido mall public key decrypts data.
Alipay's private key encrypts data, and Alipay public key decrypts data.
Generate RSA2 key
1. Generate public and private keys in Linux
$ openssl
$ OpenSSL> genrsa -out app_ private_ Key.pem 2048 # create private key RSA2
$ OpenSSL> rsa -in app_ private_ key.pem -pubout -out app_ public_ Key.pem # export public key
$ OpenSSL> exit
2. Configure public and private keys of Mido mall
Configure Mido mall private key
a. Create a new sub application pay, and create a new folder keys under the sub application to store public and private keys
Mido mall private key app to be produced_ private_ Copy key.pem to the keys folder.
b. Add payment.keys.app_ public_ The contents of the key.pem file are uploaded to Alipay.
3. configure Alipay public key
Copy the Alipay public key content to the application key folder: payment.keys.alipay_public_key.pem file.
-----BEGIN PUBLIC KEY----- Alipay public key content -----END PUBLIC KEY-----
5. Order payment function
Tips:
Order payment trigger page: order_success.html and user_center_order.html
When we fulfill the order payment function, we only need to get the login link to Alipay. After entering the Alipay system, the user pays the payment to Alipay.
1. Request method
option | programme |
---|---|
Request method | GET |
Request address | /payment/(?P<order_id>\d+)/ |
2. Request parameters: path parameters
Parameter name | type | Is it necessary to pass | explain |
---|---|---|---|
order_id | int | yes | Order No |
3. Response result: JSON
field | explain |
---|---|
code | Status code |
errmsg | error message |
alipay_url | Alipay login link |
4. Definition and implementation of back-end interface
A. Create subapplication
django-admin startapp pay
B. Add module
INSTALLED_APPS = [
'apps.pay',
]
C. Configure routing
urlpatterns = [
path('payment/<order_id>/',PayUrlView.as_view()),
]
urlpatterns = [
path('',include('apps.pay.urls')),
]
D. Business logic
""" demand: When the user clicks the pay button,To generate a jump connection from the back end front end: axios request. Carry order id back-end: request: Get order id Business logic: Creating Alipay links(Read document) Read the application private key and Alipay public key Creating an example of Alipay,Method of calling Alipay Splice connection response: route: GET payment/order_id/ step: 1. Get order id 2. Validate order id (According to order id Query order information) 3. Read the application private key and Alipay public key 4. Creating an example of Alipay 5. Call Alipay's payment method 6. Splice connection 7. Return response """ from django.views import View from apps.orders.models import OrderInfo from utils.views import LoginRequiredJSONMixin from django.http import JsonResponse from meiduo_mall import settings from alipay import AliPay, AliPayConfig class PayUrlView(LoginRequiredJSONMixin, View): def get(self, request, order_id): user = request.user # 1. Get order id # 2. Verify the order id (query the order information according to the order id) try: # For the accuracy of business logic, # Query orders to be paid order = OrderInfo.objects.get(order_id=order_id, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'], user=user) except OrderInfo.DoesNotExist: return JsonResponse({'code': 400, 'errmsg': 'No such order'}) # 3. read the application private key and Alipay public key. app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read() alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read() # 4. create Alipay example alipay = AliPay( appid=settings.ALIPAY_APPID, app_notify_url=None, # Default callback url app_private_key_string=app_private_key_string, # Alipay's public key, which verifies the use of Alipay return message, is not your own public key. alipay_public_key_string=alipay_public_key_string, sign_type="RSA2", # RSA or RSA2 debug=settings.ALIPAY_DEBUG, # Default False config=AliPayConfig(timeout=15) # Optional, request timeout ) # 5. call Alipay's payment method. # If you are a Python 3 user, use the default string subject = "Duoduo mall test order" # Computer website payment, need to jump to https://openapi.alipay.com/gateway.do? + order_string # https://openapi.alipay.com/gateway.do This is online # ' https://openapi.alipaydev.com/gateway.do 'This is a sandbox order_string = alipay.api_alipay_trade_page_pay( out_trade_no=order_id, total_amount=str(order.total_amount), # Type conversion is necessary because decimal is not the basic data type subject=subject, return_url=settings.ALIPAY_RETURN_URL, # After the payment is successful, jump to the page notify_url="https://example.com/notify "# optional. If it is not filled in, the default notify url will be used ) # 6. Splicing connection pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string # 7. Return response return JsonResponse({'code': 0, 'errmsg': 'ok', 'alipay_url': pay_url})
E. My test
Exception: Crtl+Shift+delete, empty browser cache
5. Add transaction
Add model
# Create your models here. from django.db import models from apps.orders.models import OrderInfo from utils.models import BaseModel class Payment(BaseModel): """Payment information""" order = models.ForeignKey(OrderInfo, on_delete=models.CASCADE, verbose_name='order') trade_id = models.CharField(max_length=100, unique=True, null=True, blank=True, verbose_name="Payment No") class Meta: db_table = 'tb_payment' verbose_name = 'Payment information' verbose_name_plural = verbose_name
code implementation
""" front end: When the user's payment is completed,It will jump to the specified product page There is payment related information in the request query string in the page The front end submits the data to the back end back-end: request: receive data Business logic: Convert query string to dictionary,Validation data,Verify no problem to get Alipay transaction code Change order status response: route: PUT payment/status/ step: 1. receive data 2. Convert query string to dictionary validation data 3. Verify no problem to get Alipay transaction code 4. Change order status 5. Return response Buyer account eghulw5253@sandbox.com Login password 111111 Payment password 111111 """ from apps.pay.models import Payment class PaymentStatusView(View): def put(self, request): # 1. Receive data data = request.GET # 2. Convert query string to dictionary validation data data = data.dict() # 3. verify no problem to get Alipay transaction code signature = data.pop("sign") app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read() alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read() # Creating an example of Alipay alipay = AliPay( appid=settings.ALIPAY_APPID, app_notify_url=None, # Default callback url app_private_key_string=app_private_key_string, # Alipay's public key, which verifies the use of Alipay return message, is not your own public key. alipay_public_key_string=alipay_public_key_string, sign_type="RSA2", # RSA or RSA2 debug=settings.ALIPAY_DEBUG, # Default False config=AliPayConfig(timeout=15) # Optional, request timeout ) success = alipay.verify(data, signature) if success: # Get trade_no String Required sixty-four Alipay transaction number trade_no = data.get('trade_no') order_id = data.get('out_trade_no') Payment.objects.create( trade_id=trade_no, order_id=order_id ) # 4. Change order status OrderInfo.objects.filter(order_id=order_id).update(status=OrderInfo.ORDER_STATUS_ENUM['UNSEND']) return JsonResponse({'code': 0, 'errmsg': 'ok', 'trade_id': trade_no}) else: return JsonResponse({'code': 400, 'errmsg': 'Please check the order status in the order in the personal center'})