Introduction
Integrating WeChat Pay into your WooCommerce store can significantly improve the shopping experience and payment success rate for customers in China. This tutorial guides you through using the official WeChat Pay PHP SDK to implement a robust integration, avoiding the need to build everything from scratch.
Prerequisites
Before you begin coding, ensure you have the following configured:
- WeChat Merchant Account: Apply for and activate a WeChat Pay merchant account.
- API Key: Log into the merchant platform, navigate to Account Center > API Security, and set your API key (requires installing an operation certificate).
- AppID and Merchant ID (MCHID): Note your Official Account AppID (or Mini Program/App AppID) and your Merchant ID (MCHID).
- Server Configuration: Ensure your WordPress server's IP is added to the merchant platform's IP whitelist and that you have a publicly accessible domain (for receiving payment notifications).
Install the Official WeChat Pay PHP SDK
It is recommended to install the SDK via Composer for a standardized setup.
composer require wechatpay/wechatpay
If your environment does not support Composer, you can download the SDK source code from GitHub and include it manually.
Create a WooCommerce Payment Gateway Plugin
We will create a simple plugin to add a WeChat Pay gateway. Create a new folder in your WordPress wp-content/plugins directory, for example, wechatpay-for-woocommerce, and then create the main plugin file.
Main Plugin File: wechatpay-for-woocommerce.php
<?php
/**
* Plugin Name: WooCommerce WeChat Pay Gateway
* Description: Integrates the official WeChat Pay SDK as a WooCommerce payment gateway.
* Version: 1.0.0
*/
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Ensure WooCommerce is active
add_action('plugins_loaded', 'init_wechatpay_gateway');
function init_wechatpay_gateway() {
if (!class_exists('WC_Payment_Gateway')) {
return;
}
// Include Composer autoloader (assuming SDK is installed via Composer in plugin's vendor folder)
$autoloader = plugin_dir_path(__FILE__) . 'vendor/autoload.php';
if (file_exists($autoloader)) {
require_once $autoloader;
}
// Define the payment gateway class
class WC_Gateway_WeChatPay extends WC_Payment_Gateway {
// Class definition will be expanded below
}
// Add the gateway to WooCommerce
add_filter('woocommerce_payment_gateways', 'add_wechatpay_gateway');
function add_wechatpay_gateway($gateways) {
$gateways[] = 'WC_Gateway_WeChatPay';
return $gateways;
}
}
Implementing the Payment Gateway Class
Next, within the same file, implement the core methods of the WC_Gateway_WeChatPay class.
1. Constructor and Basic Setup
public function __construct() {
$this->id = 'wechatpay';
$this->icon = ''; // Optional: URL to payment icon
$this->has_fields = false;
$this->method_title = 'WeChat Pay';
$this->method_description = 'Accept payments via the official WeChat Pay SDK.';
// Load settings fields
$this->init_form_fields();
$this->init_settings();
// Get user settings
$this->title = $this->get_option('title');
$this->description = $this->get_option('description');
$this->enabled = $this->get_option('enabled');
$this->appid = $this->get_option('appid');
$this->mchid = $this->get_option('mchid');
$this->api_key = $this->get_option('api_key');
$this->notify_url = home_url('/wc-api/wc_gateway_wechatpay/'); // Notification endpoint
// Save settings
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
// Register payment result callback handler
add_action('woocommerce_api_wc_gateway_wechatpay', array($this, 'handle_notify'));
}
2. Admin Settings Fields
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => 'Enable/Disable',
'type' => 'checkbox',
'label' => 'Enable WeChat Pay',
'default' => 'no'
),
'title' => array(
'title' => 'Title',
'type' => 'text',
'description' => 'Payment method title the customer sees during checkout.',
'default' => 'WeChat Pay',
'desc_tip' => true
),
'description' => array(
'title' => 'Description',
'type' => 'textarea',
'description' => 'Description for this payment method.',
'default' => 'Pay via WeChat Scan.'
),
'appid' => array(
'title' => 'AppID',
'type' => 'text',
'description' => 'Your Official Account or Mini Program AppID.',
'default' => ''
),
'mchid' => array(
'title' => 'Merchant ID (MCHID)',
'type' => 'text',
'description' => 'Your WeChat Pay Merchant ID.',
'default' => ''
),
'api_key' => array(
'title' => 'API Key',
'type' => 'password',
'description' => 'API key set in the merchant platform.',
'default' => ''
)
);
}
3. Processing Payment Requests (Core)
This method is called when a customer places an order and selects WeChat Pay. It creates a WeChat Pay order and returns payment parameters (e.g., QR code URL).
public function process_payment($order_id) {
$order = wc_get_order($order_id);
// 1. Initialize WeChat Pay client
$wechatpay = $this->init_wechatpay_client();
// 2. Build request parameters (using Native payment as an example)
$requestData = [
'mchid' => $this->mchid,
'out_trade_no' => $order->get_order_number(),
'appid' => $this->appid,
'description' => 'Order: ' . $order->get_order_number(),
'notify_url' => $this->notify_url,
'amount' => [
'total' => intval($order->get_total() * 100), // Convert to cents
'currency' => 'CNY'
]
];
try {
// 3. Call SDK to create order
$resp = $wechatpay->chain('v3/pay/transactions/native')->post(['json' => $requestData]);
$result = json_decode($resp->getBody(), true);
// 4. Get QR code URL
$code_url = $result['code_url'];
// 5. Set order status to "pending" and store QR code URL
$order->update_status('pending', 'Awaiting customer WeChat scan.');
update_post_meta($order_id, '_wechatpay_qrcode_url', $code_url);
// 6. Redirect to custom "show QR code" page
return array(
'result' => 'success',
'redirect' => $order->get_checkout_payment_url(true)
);
} catch (Exception $e) {
wc_add_notice('Payment request failed: ' . $e->getMessage(), 'error');
return array('result' => 'failure');
}
}
// Helper: Initialize SDK client
private function init_wechatpay_client() {
// Merchant API private key (assume you have saved the .pem file)
$merchantPrivateKeyFilePath = plugin_dir_path(__FILE__) . 'cert/apiclient_key.pem';
$merchantPrivateKey = file_get_contents($merchantPrivateKeyFilePath);
$merchantId = $this->mchid;
$merchantSerialNumber = 'YOUR_MERCHANT_CERT_SERIAL_NUMBER'; // Get from merchant platform
// Simplified builder example. In production, implement platform certificate caching.
$wechatpay = WeChatPayBuilder::factory([
'mchid' => $merchantId,
'serial' => $merchantSerialNumber,
'privateKey' => $merchantPrivateKey,
'certs' => [ /* Platform certificates */ ],
'secret' => $this->api_key, // API v3 Key
]);
return $wechatpay;
}
4. Handling Payment Result Notifications
WeChat Pay servers will send a POST request to your notification URL. You must verify and process it correctly.
public function handle_notify() {
$body = file_get_contents('php://input');
$headers = getallheaders(); // Note: May need adjustment for some environments
try {
$wechatpay = $this->init_wechatpay_client();
// In practice, use SDK's decrypt/verify tools: $inWechatpay->decrypt($headers, $body)
$data = json_decode($body, true);
$out_trade_no = $data['out_trade_no'];
// Adjust logic to find order by your custom order number
$order = wc_get_order(wc_get_order_id_by_order_key($out_trade_no));
if ($order && $data['trade_state'] === 'SUCCESS') {
// Payment successful
$order->payment_complete();
$order->add_order_note('WeChat Pay successful. Transaction ID: ' . $data['transaction_id']);
header('HTTP/1.1 200 OK');
echo json_encode(['code' => 'SUCCESS', 'message' => 'OK']);
} else {
header('HTTP/1.1 500 Internal Server Error');
}
} catch (Exception $e) {
header('HTTP/1.1 500 Internal Server Error');
error_log('WeChat Pay notification error: ' . $e->getMessage());
}
exit;
}
Displaying the Payment QR Code
You need to create a page template or use hooks to display the QR code retrieved in the process_payment step. A simple example:
// Add shortcode or custom template on payment page
$qrcode_url = get_post_meta($order_id, '_wechatpay_qrcode_url', true);
echo '<div class="wechatpay-qrcode"><img src="' . esc_url($qrcode_url) . '" alt="WeChat Pay QR Code" /></div>';
Important Notes and Security Recommendations
- Certificate Management: Keep merchant private keys secure; never commit them to code repositories. Implement automatic updates for platform certificates.
- Notification Verification: Always verify the signature of WeChat Pay notifications to ensure legitimacy and prevent fraud.
- Order Status: Update order status based solely on the asynchronous notification (
handle_notify), not front-end callbacks. - Error Handling: Implement robust exception handling and logging for production environments.
- Testing: Test thoroughly using the WeChat Pay sandbox or small real transactions before going live.
Conclusion
Following these steps, you have successfully integrated the official WeChat Pay SDK with WooCommerce. This tutorial provides a complete workflow and example code, from plugin creation and SDK initialization to payment processing and notification handling. Adapt the interfaces and parameters for your specific use case (e.g., Official Account or Mini Program payments) and always adhere to WeChat Pay's official documentation and security guidelines.