--- title: WeChat Pay Server To Server Integration permalink: /en/notes/paymentMethods/WeChatPay/s2s/ createTime: '2025/08/08 15:00:00' description: >- WeChat Pay Server To Server integration documentation introduces how to implement WeChat Pay through S2S method. Applicable to PC, mobile browser and Webview payment scenarios, covering mainland China. Key parameters include `device.orderTerminal` and `shopperIP`. Supports direct WeChat Pay launch or payment process handling through intermediate pages, ensuring --- ## WeChat Pay-Server To Server Interaction Flow ```mermaid %%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#E3F2FD', 'primaryTextColor': '#0D47A1', 'primaryBorderColor': '#1976D2', 'lineColor': '#1565C0', 'secondaryColor': '#BBDEFB', 'tertiaryColor': '#90CAF9', 'background': '#F8FBFF', 'mainBkg': '#E3F2FD', 'secondBkg': '#BBDEFB', 'tertiaryBkg': '#90CAF9', 'actorBkg': '#2196F3', 'actorBorder': '#1976D2', 'actorTextColor': '#FFFFFF', 'actorLineColor': '#1565C0', 'signalColor': '#0D47A1', 'signalTextColor': '#0D47A1', 'c0': '#E8F4FD', 'c1': '#D1E7DD', 'c2': '#B3D9FF', 'c3': '#81C784', 'noteBkgColor': '#E1F5FE', 'noteTextColor': '#01579B', 'noteBorderColor': '#0288D1', 'loopTextColor': '#0D47A1', 'activationBkgColor': '#B3E5FC', 'activationBorderColor': '#0277BD' } }}%% sequenceDiagram participant User as 👤 User participant Frontend as 💻 Merchant Frontend participant Merchant as 🏪 Merchant Backend participant PP as 🔄 PingPong Server participant WeChat as 💬 WeChat Pay Note over User, WeChat: 🚀 WeChat Pay Server To Server Integration Process Note over User, Frontend: 📋 Preparation Phase:• User selects payment• Merchant builds own checkout User->>Frontend: 1. User enters merchant checkout page User->>Frontend: 2. Select WeChat Pay payment method Frontend->>+Merchant: 3. Submit order information Note right of Merchant: Order verification
Amount calculation Merchant->>+PP: 4. Call create order and pay API Note right of PP: Create payment order
Get WeChat Pay parameters PP-->>-Merchant: 5. Return payment parameters (QR code/call-up parameters) Merchant->>-Frontend: 6. Return payment parameters to frontend Note over Frontend, WeChat: 💳 WeChat Pay Interaction alt 🖥️ [PC Payment] Frontend->>Frontend: 7. 6a️⃣ Display WeChat Pay QR code User->>WeChat: 8. 7a️⃣ User scans QR code to pay WeChat->>WeChat: 9. User completes payment authorization else 📱 [Mobile Payment] Frontend->>+WeChat: 10. 6b️⃣ Launch WeChat client Note right of WeChat: H5 redirect to WeChat Pay
or direct payment in WeChat User->>WeChat: 11. 7b️⃣ User completes payment authorization WeChat-->>-Frontend: 12. Payment result page redirect end WeChat->>+PP: 13. WeChat Pay result notification PP->>PP: 14. Process payment result Note right of PP: • Verify payment result• Update order status• Risk control check PP->>+Merchant: 15. 🔟 Asynchronous notification of payment result Note right of Merchant: Order status update
Business logic processing Merchant-->>-PP: 16. Confirm notification received alt ✅ [Payment Success] PP-->>WeChat: 17. Payment processing completed Note over Frontend, Merchant: 🔄 Status polling (optional) Frontend->>+Merchant: 18. 1️⃣ Poll payment status Merchant-->>-Frontend: 19. Return latest status Frontend->>Frontend: 20. 2️⃣ Display payment success page Note over Frontend: Merchant custom logic
Payment completion processing else ❌ [Payment Failed] PP-->>WeChat: 21. Payment failure processing Frontend->>Frontend: 22. Display payment failure page Note right of Frontend: Error handling
User notification end Note over User, PP: 🎯 WeChat Pay Server To Server Process Completed ``` ## Integration Navigation ### Step1 Call Create Order and Pay Use the Create Order and Pay interface to directly initiate WeChat Pay ### Step2 Handle Payment Response Handle returned payment parameters according to different payment scenarios: **Key Parameter Description:** 1. `device.orderTerminal` - 02-PC browser(pc) - 04-SDK(ios) - 05-SDK(Android) 2. `shopperIP` - User's public IP address, required by WeChat Pay, otherwise will cause error - Please obtain the real consumer IP address, cannot use localhost, 127.0.0.1 or other loopback addresses ## PC Payment `device.orderTerminal` = `02` Create order and pay interface return parameters: - `qrCode` : WeChat's `qrCode`, merchant needs to handle QR code display - `paymentRedirectUrl` : PingPongCheckout wrapped QR code page, just redirect to this page ## Mobile Browser Payment `device.orderTerminal` = `04` or `05` Create order and pay interface return parameters: - `paymentRedirectUrl` : Corresponds to WeChat's `mwebUrl` parameter ## Webview Payment `device.orderTerminal` = `04` or `05` Create order and pay interface return parameters: - `paymentRedirectUrl` : Corresponds to WeChat's `mwebUrl` parameter ### Solution 1: Webview Directly Launch WeChat Pay ::: steps 1. **Request create order and pay interface, get `paymentRedirectUrl`.** 2. **Set Referer** **Android: Add Referer when loadUrl** ```kotlin val headers = mutableMapOf() headers["Referer"] = "https://your-domain.com" // Must be consistent with authorized domain webView.loadUrl(mwebUrl, headers) ``` **iOS: Set Referer in request header (WKWebView)** ```swift guard let url = URL(string: mwebUrl) else { return } var request = URLRequest(url: url) request.setValue("https://your-domain.com", forHTTPHeaderField: "Referer") webView.load(request) ``` 3. Launch WeChat and pay ::: ### Solution 2: Launch WeChat Pay Through Intermediate Page ::: steps 1. **Request create order and pay interface, get `paymentRedirectUrl`.** 2. **Create pay-proxy intermediate page** ```html ``` 3. **Create back callback page** ```html ``` 4. **App WebView loads intermediate page** ```kotlin webView.loadUrl("https://intermediate-page-domain/pay-proxy?orderId=123") ``` 5. **Intercept and launch WeChat** ```kotlin override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { val url = request?.url?.toString() ?: return false if (url.startsWith("weixin://")) { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) return true } if (url.startsWith("yourapp://")) { handlePayResult(url) return true } return false } ``` 6. **Receive callback and refresh order** Parse parameters in `handlePayResult(url)`, close WebView, query backend order status. :::