Django realizes Alipay payment (sandbox environment)

Keywords: Python Django Back-end

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

optionprogramme
Request methodGET
Request address/payment/(?P<order_id>\d+)/

2. Request parameters: path parameters

Parameter nametypeIs it necessary to passexplain
order_idintyesOrder No

3. Response result: JSON

fieldexplain
codeStatus code
errmsgerror message
alipay_urlAlipay 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'})

Display fresh fruit

Posted by EnDee321 on Sun, 31 Oct 2021 19:42:02 -0700