About WeChat Mini Program to implement cloud payment

About WeChat Mini Program to implement cloud payment

1. Introduction

Anyone who has played around with WeChat Mini Program Cloud Development knows that WeChat Mini Program Cloud Development currently supports cloud payment.

So with the support of cloud payment capabilities, what is the entire payment process like?

For example: what should the logical processing be like before, during, and after a user initiates a payment? How should it be designed to be safer and reduce the probability of errors?

This article mainly introduces the use of cloud payment and how to design the order system and payment process under cloud payment.

By the way: WeChat payment function only supports calls by corporate entities .

2. Thought Analysis

The calling process of cloud payment is roughly divided into the following four steps:

1. Obtain authentication-free parameters

After the mini program passes in basic parameters such as amount and product information, it calls the cloud function to obtain the authentication-free parameters.

2. Pass the authentication-free parameters to the payment API on the mini program side

The cloud function returns the authentication-free parameter, which is used as the input parameter of the payment API on the mini program side.

3. User payment

Invoke WeChat Pay, and the user makes payment/cancels payment

4. WeChat calls back the specified cloud function

This cloud function is called back after payment is successful.

If the user cancels the payment, this cloud function will not be called back.

Then, based on the above four steps, we can analyze when the order was created and when the order payment status was changed.

The creation of an order should be when obtaining the authentication-free parameters in the first step. After obtaining the authentication-free parameters, the order number and other information should be inserted into the database.

The order payment status at this time should be pending payment .

At the same time, you can also know that the change of order payment status should be made in the fourth step. If the payment is successful, change the payment status of the order to payment successful.

Related official documentation links:

  • Cloud Payment Documentation
  • Cloud payment callback document
  • Call the payment API document on the mini program

3. Cloud payment case study

1. Cloud Function

1-1. Get authentication-free parameter cloud function (wxPay)

This cloud function is mainly used to obtain the parameters required by the payment API and create an order to insert into the database.

Screenshot of successful call example result

Implementation Code

// Cloud function entry file const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

const db = cloud.database()

exports.main = async (event) => {

  const wxContent = cloud.getWXContext() // openid and other information const openid = wxContent.OPENID
  const appid = wxContent.APPID

  const totalFee = event.totalFee // Payment amount (unit: cents)
  const body = event.body // Product name const outTradeNo = createOutTradeNo() // Order number // Get authentication-free payment parameters const payMent = await cloud.cloudPay.unifiedOrder({
    "body": body,
    "outTradeNo": outTradeNo,
    "spbillCreateIp": "127.0.0.1",
    "subMchId": "Merchant Number", //Merchant Number "totalFee": totalFee,
    "envId": "Corresponding cloud environment id", // Cloud environment id
    "functionName": "payCallBack" // Payment callback cloud function})

  // Create an order const nowTime = new Date().getTime()
  const orderObj = {
    _openid: openid,
    appid: appid,
    outTradeNo: outTradeNo,
    totalFee: totalFee * 0.01,
    payStatus: 'wait',
    createTime: nowTime,
    updateTime: nowTime,
    deleteTime: null,
  }
  await addOrder(orderObj)

  return payMent
}

/** Create a random unique order number (32 bits) */
const createOutTradeNo = () => {
  let outTradeNo = new Date().getTime() // Get the current 13-digit timestamp let numStr = '0123456789';
  let randomStr = '';
  for (let i = (32 - 13); i > 0; --i) {
    randomStr += numStr[Math.floor(Math.random() * numStr.length)];
  }
  outTradeNo += randomStr
  return outTradeNo
}

/** Create an order to the database */
const addOrder = async (orderObj) => {
  return await db.collection('order')
    .add({
      data:orderObj
    })
    .then(res => {
      console.log("Order created successfully=====>", res, orderObj)
    })
    .catch(err => {
      console.log("Create order exception =====>", err, orderObj)
    })
}

1-2. Payment callback cloud function (payCallBack)

After the user pays successfully, the WeChat server will call this cloud function and carry the payer's order number, openid, appid and other information.

Developers can use this to determine which order is currently being called back.

Callback documentation

Example screenshot of successful callback result

Implementation Code

// Cloud function entry file const cloud = require('wx-server-sdk')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

const db = cloud.database()

// Cloud function entry function exports.main = async (event) => {
  console.log("Callback return object =====>", event)
	// Judgment condition if (event.returnCode == 'SUCCESS') {
    if (event.resultCode == 'SUCCESS') {
      // Query condition const whereObj = {
        appid: event.subAppid, // APPID of the mini program
        _openid: event.subOpenid, // Mini Program user's openid
        outTradeNo: event.outTradeNo, // Order number of the merchant number}
      // Update object const updateObj = {
        transactionId: event.transactionId, // WeChat's order number totalFee: event.totalFee * 0.01, // WeChat's received amount timeEnd: event.timeEnd, // Payment end time payStatus: 'success',
        updateTime: new Date().getTime()
      }
      // Update order await updateOrder(whereObj, updateObj)
    }
  }
  // Return protocol and input protocol of payment callback (this structure must be returned, see the document for details)
  return {
    errcode: 0,
    errmsg: event.resultCode
  }
}

/** Update the payment status of the order */
const updateOrder = async (whereObj, updateObj) => {
  return await db.collection('order')
    .where(whereObj)
    .update({
      data:updateObj
    })
}

2. Mini program side (js code)

// pages/wxPay/wxPay.js
Page({

  /**
   * Initial data of the page */
  data: {

  },

  /**
   * Life cycle function--listen for page loading*/
  onLoad() {},

  /**
   * Life cycle function--monitor page display*/
  onShow() {},

  /**Payment click monitoring*/
  async payTap() {
    const totalFee = 2
    const body = 'payment test'
    wx.showLoading({
      title: 'Starting WeChat payment',
      mask: true
    })

    // Get payment authentication-free parameters const payMentRes = await this.getPayMent(totalFee, body)
    wx.hideLoading({
      success: (res) => {},
    })
    // Mini Program Payment API
    const payRes = await this.wxPay(payMentRes.result.payment)
    //Payment API return result print console.log(payRes)
  },

  /**
   * Mini Program Payment API
   * @param {object} payment authentication-free parameter*/
  wxPay(payment) {
    return new Promise((resolve, rejects) => {
      wx.requestPayment({
        ...payment,
        success(res) {
          resolve({
            status: 'success',
            res: res
          })
        },
        fail(err) {
          resolve({
            status: 'fail',
            res: err
          })
        }
      })
    })
  },

  /**
   * Get payment authentication-free parameters* @param {number} totalFee payment amount, unit: cents* @param {string} body product name*/
  getPayMent(totalFee, body) {
    return new Promise((resolve, rejects) => {
      wx.cloud.callFunction({
        name: 'wxPay',
        data: {
          totalFee,
          body
        },
        success(res) {
          resolve(res)
        },
        fail(err) {
          resolve(err)
        }
      })
    })
  },

})

3. Payment results

User side

Merchant side

4. Code directory structure

4. Why write like this

Maybe some students have used WeChat Cloud Payment, but have never used the above mentioned Payment callback cloud function.

However, it is also possible to obtain the user's payment results.

As shown below

In fact, the payment API( wx.requestPayment()) can also return the current payment result. It is indeed possible to use the result of this callback to determine whether the payment is successful.

In this case, why do we need to write a payment callback cloud function to get the payment result?

Seeing this also means that you have completed the entire implementation process. If you have any questions about why it is implemented in this way, you should be able to find some answers for yourself.

Apart from minor issues related to development specifications and optimization, I would like to tell you a very fatal reason.

WeChat Mini Program Payment API( wx.requestPayment()) has a fatal problem on the iOS side.

After the user pays, he will enter the following page

If the user does not click the Done button, the WeChat Mini Program’s payment API ( wx.requestPayment()) callback will not be triggered.

In other words, the mini program itself cannot obtain the user’s payment results.

Assuming the user directly exits WeChat, the mini program will be destroyed. At this time, how should the order status change?

Tips: This problem will not occur on the Android side. Students who are interested can practice the following by themselves.

V. Conclusion

This is the idea, but some exception handling needs to be handled by developers themselves during the development process, such as order insertion failure, update failure and other exception problems. Although the probability is small, and there are printed call records, if there is a problem, the call records and related information can also be checked.

This is the end of this article about how to implement cloud payment in WeChat Mini Program. For more relevant WeChat Mini Program cloud payment content, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • WeChat Mini Programs - Detailed explanation of WeChat login, WeChat payment, and template messages
  • WeChat applet payment backend java implementation example
  • PHP: WeChat applet WeChat payment server integration example detailed explanation and source code download
  • Summary of WeChat Mini Program Payment Function Development Errors
  • WeChat Mini Program Payment Simple Example and Notes
  • WeChat Mini Program Payment and Refund Process Detailed Explanation
  • WeChat applet payment function implementation PHP example detailed explanation
  • WeChat applet WeChat payment access development example detailed explanation
  • How to implement WeChat applet calling WeChat payment interface
  • Implementation of WeChat applet payment function (front end)

<<:  A brief discussion on how to modify/set the environment variable JAVA_HOME under Linux

>>:  Implementation of running SQL Server using Docker

Recommend

How to set utf-8 encoding in mysql database

Modify /etc/my.cnf or /etc/mysql/my.cnf file [cli...

How to enter directory/folder in Linux without using CD command

As we all know, without the cd command, we cannot...

Best Practices Guide for MySQL Partitioned Tables

Preface: Partitioning is a table design pattern. ...

9 Tips for MySQL Database Optimization

Table of contents 1. Choose the most appropriate ...

Supplementary article on front-end performance optimization

Preface I looked at the previously published arti...

MySQL query tree structure method

Table of contents MySQL query tree structure 1. A...

mysql5.7.17.msi installation graphic tutorial

mysql-5.7.17.msi installation, follow the screens...

Implementation of Docker to build Zookeeper&Kafka cluster

I've been learning Kafka recently. When I was...

Solution - BASH: /HOME/JAVA/JDK1.8.0_221/BIN/JAVA: Insufficient permissions

1) Enter the folder path where the jdk file is st...

HTML table markup tutorial (16): title horizontal alignment attribute ALIGN

By default, the table title is horizontally cente...

Nginx service 500: Internal Server Error one of the reasons

500 (Internal Server Error) The server encountere...

New ways to play with CSS fonts: implementation of colored fonts

What if you designers want to use the font below ...

Summary of JavaScript JSON.stringify() usage

Table of contents 1. Usage 1. Basic usage 2. The ...