Implement WeChat|Alipay payment in uni-app

1. Main logic

1. What you might need to pay for

  1. Payment methods【WeChat】【Alipay】

  2. amount paid

  3. title of the order

  4. order number

  5. The validity period of the order

  6. Pay to complete the jump link

2. Pay

2.1. When you click Buy Now, you want to send an ajax request to the backend, and the complete process of carrying information in the request

ajax({
	url:'xxxx',   =====》前端给后端传递的数据
	data:{
		用户id,
		****订单的金额
		****订单的商品系类
	},
	success:function(){  ===》后端给前端返回的数据
		if(data.xxx){
			data是一个对象,通常含有订单号
			然后跳转到确认订单页面
		}
		
	}

})

2.2. Confirm order page ===>Click to submit order===>Select payment method (request will be sent before payment)

2.2.1 Double check whether the user's choice is consistent with the method returned by the backend

````
ajax({
	data:{  ===>前端给后端传递数据
		appid:'已经准备好的(通常是公司申请的id(用来收钱的)'
		订单号
		选择了那种支付方式
	},
	success:function(){
		1.后端会返回true,代表可以支付了
		2.还会返回一个标示(那种支付方式
		if(后端给前端传递的哪种支付方式===用户点击的哪种支付方式){
			//成立情况下,则开始发起支付的请求(这时候需要对接支付宝或微信支付官方了)
			发起支付	
		}
		
	}
})
````

2.2.2 Docking official payment

Pass some of the data obtained to Alipay|WeChat payment official

Summary 1 : When the user clicks to buy, the payment request is not immediately invoked, but the request is sent to the backend, and the backend returns the order number. The meaning of returning the order number is that when the user clicks to submit the order, the order number is passed to the backend to know the status of the order, and at the same time, the backend is notified of the payment method selected by the user, and finally the backend performs return verification. Finally, send the payment request according to the data returned by the backend (docking official) - this payment request is generally packaged, you only need to pass some data

After the front end gets the order number, it sends a request to the back end.

 

3. Use in uni-app:

All the front end has to do is:

  1. Request the backend interface and get the orderinfo (order information). According to the official new order information, this order information is a string directly spliced ​​by the backend, and the frontend does not need other operations
  2. Call payment API: uni.requestPayMent
  3. handle callback

Pay attention to the problem:

  1. The format of the order is returned by the backend, and the frontend does not need to do any processing. No matter what kind of payment, the information of the order is the habit of the strng class
  2. The WeChat payment id in mainfest.json in uni-app needs to be added to the appid applied for mobile application payment on the WeChat development platform, because several appids may be encountered, and it took a long time for this reason
  3. When applying for mobile payment on the open platform, the application package name can be chosen by yourself, and the application signature needs to be generated according to the instructions of WeChat or a certificate generated online (the certificate can be a signature generated by md5), all lowercase without colons - this step Similar to calling the configuration in Gaode map
  4. The only merchant order number is for the entire project, there may be multiple transaction records, and the order number cannot be repeated
//微信orderinfo格式   
 "{\"appid\":\"xxxxxxxx\",\"partnerid\":\"xxxxxxx\",\"prepayid\":\"xxxxxxxxxxxxxxxx\",\"timestamp\":\"1579779903\",\"noncestr\":\"xxxxxxx\",\"package\":\"Sign": "WXPay\",\"sign\":\"xxxxxxxxxxxxxxxxxxxx\"}"  


//支付宝orderinfo格式  
app_id=xxxxxxxxx&method=xxxxxxxxxx&format=JSON&charset=UTF-8&sign_type=RSA2&version=1.0&return_url=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx&notify_url=xxxxx&timestamp=xxxxxx&sign=xxxxxxx&biz_content=xxxxxxxxxx
Main code:
<template>
    <view>
        <page-head :title="title"></page-head>
        <view class="uni-padding-wrap">
            <view style="background:#FFF; padding:50upx 0;">
                <view class="uni-hello-text uni-center">支付金额</text></view>
                <view class="uni-h1 uni-center uni-common-mt">
                    <text class="rmbLogo">¥</text>
                    <input class="price" type="digit" :value="price" maxlength="4" @input="priceChange" />
                </view>
            </view>
            <view class="uni-btn-v uni-common-mt">
                <!-- #ifdef APP-PLUS -->
                <template v-if="providerList.length > 0">
                    <button v-for="(item,index) in providerList" :key="index" @click="requestPayment(item,index)"
                        :loading="item.loading">{
   
   {item.name}}支付</button>
                </template>
                <!-- #endif -->
            </view>
        </view>
    </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                title: 'request-payment',
                loading: false,
                price: 1,
                providerList: []
            }
        },
        onLoad: function() {
            // #ifdef APP-PLUS
            uni.getProvider({
                service: "payment",
                success: (e) => {
                    console.log("payment success:" + JSON.stringify(e));
                    let providerList = [];
                    e.provider.map((value) => {
                        switch (value) {
                            case 'alipay':
                                providerList.push({
                                    name: '支付宝',
                                    id: value,
                                    loading: false
                                });
                                break;
                            case 'wxpay':
                                providerList.push({
                                    name: '微信',
                                    id: value,
                                    loading: false
                                });
                                break;
                            default:
                                break;
                        }
                    })
                    this.providerList = providerList;
                },
                fail: (e) => {
                    console.log("获取支付通道失败:", e);
                }
            });
            // #endif
        },
        methods: {
            async requestPayment(e, index) {
                this.providerList[index].loading = true;
                let orderInfo = await this.getOrderInfo(e.id);
                console.log("得到订单信息", orderInfo);
                if (orderInfo.statusCode !== 200) {
                    console.log("获得订单信息失败", orderInfo);
                    uni.showModal({
                        content: "获得订单信息失败",
                        showCancel: false
                    })
                    return;
                }
                uni.requestPayment({
                    provider: e.id,
                    orderInfo: orderInfo.data.data,
                    success: (e) => {
                        console.log("success", e);
                        uni.showToast({
                            title: "感谢您的赞助!"
                        })
                    },
                    fail: (e) => {
                        console.log("fail", e);
                        uni.showModal({
                            content: "支付失败,原因为: " + e.errMsg,
                            showCancel: false
                        })
                    },
                    complete: () => {
                        this.providerList[index].loading = false;
                    }
                })
            },
            getOrderInfo(e) {
                let appid = "";
                // #ifdef APP-PLUS
                appid = plus.runtime.appid;
                // #endif
                let url = 'http://10.10.60.200:8070/sc-admin/sales/wx/prepay/?brokerId=shba01';
                return new Promise((res) => {
                    uni.request({
                        url: url,
                        success: (result) => {
                            res(result);
                        },
                        fail: (e) => {
                            res(e);
                        }
                    })
                })
            },
            priceChange(e) {
                console.log(e.detail.value)
                this.price = e.detail.value;
            }
        }
    }
</script>

<style>
    .rmbLogo {
        font-size: 40upx;
    }

    button {
        background-color: #007aff;
        color: #ffffff;
    }

    .uni-h1.uni-center {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: flex-end;
    }

    .price {
        border-bottom: 1px solid #eee;
        width: 200upx;
        height: 80upx;
        padding-bottom: 4upx;
    }

    .ipaPayBtn {
        margin-top: 30upx;
    }
</style>

A concise version of the comprehension code:

uni.requestPayment({  
    provider: 'alipay',  
    orderInfo: '后端返回的orderinfo字符串',  
    success: res => {  
        // 进入此回调说明支付成功  
    },  
    fail: err => {  
        const message = err.errMsg || '';  
        if (message.indexOf('[payment支付宝:62001]') !== -1) {  
            uni.showModal({  
                content: '您已取消支付。如有需要,您可在我的订单里重新付款。30分钟内有效。',  
                showCancel: false  
            });  
        } else {  
            uni.showModal({  
                content: '支付失败,原因为: ' + message,  
                showCancel: false  
            });  
        }  
    },  
    complete: () => {  
        this.submitting = false;  
        }  
    });

Guess you like

Origin blog.csdn.net/weixin_46872121/article/details/123316513