Integrating WeChat Payment into Mini Programs

Payment Architecture Overview

The payment integration involves three main participants: the user, the mini program client, and the backend server. The flow spans from user authentication through order creation, payment initialization, transaction execution, and order verification.

User Interaction Flow

  1. User browses products and adds items to cart
  2. User submits order request
  3. Mini program redirects to payment confirmation
  4. User completes payment via WeChat
  5. System confirms payment and updates order status

Technical Implementation

Authentication and Token Acquisition

Before creating orders, the mini program must authenticate users and obtain a valid session. The button component with getUserInfo provides user details, while wx.login() retrieves the login code for backend verification.

async function authenticateUser(event) {
  const { encryptedData, rawData, iv, signature } = event.detail;
  const { code } = await wxLogin();
  
  const authParams = {
    encryptedData,
    rawData,
    iv,
    signature,
    code
  };
  
  const { token } = await apiRequest({
    url: "/auth/wechat-login",
    data: authParams,
    method: "POST"
  });
  
  wx.setStorageSync('authToken', token);
  return token;
}

The backend uses auth.code2Session to exchange the code for openid and session_key, then issues a token for subsequent API requests.

Order Creation

With the token stored, include it in the Authorization header for protected endpoints:

async function createOrder(orderData) {
  const authHeader = {
    Authorization: wx.getStorageSync('authToken')
  };
  
  const response = await apiRequest({
    url: "/orders/create",
    method: "POST",
    data: orderData,
    header: authHeader
  });
  
  return response.orderId;
}

Prepayment Processing

Send the order number to the backend, which validates the pending status and calls the WeChat unified order API:

async function initiatePrepayment(orderId) {
  const paymentConfig = await apiRequest({
    url: "/payment/prepare",
    method: "POST",
    data: { orderId },
    header: { "content-type": "application/x-www-form-urlencoded" }
  });
  
  return paymentConfig;
}

The backend constructs a signed request to https://api.mch.weixin.qq.com/pay/unifiedorder and returns the prepay_id along with other rqeuired parameters.

Backend Random String Generation

Java utility for generating nonce strings:

public class PaymentUtils {
    public static String generateNonceString(int length) {
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random generator = new Random();
        StringBuilder nonce = new StringBuilder();
        
        for (int i = 0; i < length; i++) {
            int index = generator.nextInt(chars.length());
            nonce.append(chars.charAt(index));
        }
        return nonce.toString();
    }
}

Signature Generation Process

Signatures ensure request integrity. Follow these steps:

  1. Collect all parameters except sign into map M
  2. Sort keys alphabetically (ASCII order)
  3. Concatenate as key1=value1&key2=value2 forming stringA
  4. Append &key= + merchant secret key to stringA
  5. Compute MD5 hash of the combined string
  6. Convert result to uppercase

Merchant key location: WeChat Merchant Platform → Account Settings → API Security → Key Setup

Java Signature Implementation

public class SignatureVerifier {
    
    public static String createSignature(Map<String, Object> parameters, 
                                         String merchantKey) {
        Set<String> keySet = parameters.keySet();
        String[] sortedKeys = keySet.toArray(new String[0]);
        Arrays.sort(sortedKeys);
        
        StringBuilder builder = new StringBuilder();
        
        for (int i = 0; i < sortedKeys.length; i++) {
            String key = sortedKeys[i];
            Object value = parameters.get(key);
            
            if (i > 0) {
                builder.append("&");
            }
            builder.append(key).append("=").append(value != null ? value : "");
        }
        
        builder.append("&key=").append(merchantKey);
        
        return md5UpperCase(builder.toString());
    }
    
    private static String md5UpperCase(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes("UTF-8"));
            StringBuilder hex = new StringBuilder();
            
            for (byte b : digest) {
                String hexStr = Integer.toHexString(b & 0xFF);
                if (hexStr.length() == 1) {
                    hex.append("0");
                }
                hex.append(hexStr);
            }
            return hex.toString().toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException("MD5 computation failed", e);
        }
    }
}

Executing Payment

Once the backend returns payment parameters, trigger the native WeChat payment dialog:

async function executePayment(paymentParams) {
  try {
    await wx.requestPayment({
      timeStamp: paymentParams.timeStamp,
      nonceStr: paymentParams.nonceStr,
      package: paymentParams.package,
      signType: paymentParams.signType || 'MD5',
      paySign: paymentParams.paySign
    });
    
    console.log('Payment successful');
  } catch (error) {
    console.error('Payment failed:', error);
  }
}

Order Status Verification

After payment attempts, verify the order state through the backend:

async function verifyOrderStatus(orderId) {
  const status = await apiRequest({
    url: "/orders/status",
    method: "POST",
    data: { orderId }
  });
  
  return status;
}

Security Considerations

  • Never expose merchant keys in client-side code
  • Always validaet order status server-side after payment callbacks
  • Use HTTPS for all API communications
  • Implement idempotency for order creation to prevent duplicates
  • Store session_key securely and never transmit it unnecessarily

Tags: WeChat Mini Program Payment Integration Backend Development javascript java

Posted on Sun, 09 Aug 2026 16:45:19 +0000 by wata