Step‑by‑Step Guide to Integrate WeChat Pay with Webman‑Admin

This tutorial walks you through the entire process of enabling WeChat Pay in a Webman‑Admin project, covering merchant registration, certificate handling, backend configuration, PHP code setup, front‑end JS integration, asynchronous callbacks, and logging details.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Step‑by‑Step Guide to Integrate WeChat Pay with Webman‑Admin

Introduction

The article provides a comprehensive tutorial for integrating WeChat Pay into the open‑source Webman‑Admin backend framework.

Prerequisites

Apply for a WeChat Pay merchant account via the official portal.

Obtain the merchant number and set up an authorized domain (format http://yourdomain/).

Certificate Acquisition

Log in to the WeChat merchant platform.

Retrieve the merchant ID.

Add the payment authorization domain.

Install any required certificates as prompted.

Configure API security settings.

Apply for an API certificate (skip if already available).

Generate the API certificate and download it.

Extract the certificate package and keep the _cert.zip file.

Verify the merchant ID and name, then proceed.

Copy the certificate content using the provided tool.

Open the merchant platform in a browser.

Copy the certificate string.

Switch to the certificate utility.

Inspect the certificate folder.

Save the certificate files (e.g., apiclient_key.pem, apiclient_cert.pem) under the public/cert/wechat directory.

Unzip the certificate package for later use.

Configure the API secret key (32‑character alphanumeric string).

Backend Dependency Installation

composer require yansongda/pay ^3.0.0

Configuration File

Create config/payment.php with the following structure (only essential fields shown):

<?php
return [
    'wechat' => [
        'default' => [
            'mch_id' => '12312312321',
            'mch_secret_key' => '3324324reewrwerew',
            'mch_secret_cert' => public_path().'/cert/wechat/apiclient_key.pem',
            'mch_public_cert_path' => public_path().'/cert/wechat/apiclient_cert.pem',
            'notify_url' => 'http://webman.tinywan.com/gateway/payment/wechat-notify',
            'return_url' => 'http://webman.tinywan.com/index',
            // optional app IDs for various platforms
            'mp_app_id' => 'dsfdsfdsfdsdfdsafds',
            // ... other optional fields ...
            'mode' => \Yansongda\Pay\Pay::MODE_NORMAL,
        ],
    ],
    // ... unipay and logger configuration omitted for brevity ...
];
Note: Place the certificate files inside the public directory of the project.
webman.tinywan.com/public$ tree -L 4
.
├── 404.html
├── cert
│   └── wechat
│       ├── apiclient_cert.p12
│       ├── apiclient_cert.pem
│       ├── apiclient_key.pem
│       └── 证书使用说明.txt

Usage – Initialization

Load the configuration at runtime:

Pay::config(\config('payment'));
The example uses the WeChat public account (MP) payment method.

Server‑Side Payment Code (WeChat MP)

use support\Request;
use Webman\Config;
use Yansongda\Pay\Pay;

public function recharge(Request $request): Response
{
    $user['username'] = 'Tinywan';
    $user['openid'] = 'fsdfsd342343241231fdsfsdafsd';
    $order_sn = time();
    $totalAmount = 0.01;
    $discountAmount = 0;
    $payAmount = $totalAmount - $discountAmount;

    Pay::config(\config('payment'));
    $preOrder = [
        'out_trade_no' => $order_sn,
        'description' => $user['username'] . ',充值开源技术小栈',
        'amount' => ['total' => $payAmount * 100],
        'payer' => ['openid' => $user['openid']],
    ];
    $wechatRes = Pay::wechat()->mp($preOrder);
}
Route for this endpoint: /test/recharge

Front‑End JavaScript (Layui + WeChat JS SDK)

<!-- Include Layui CSS and JS, jQuery, and WeChat JS SDK -->
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.7.6/css/layui.css">
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script src="https://www.layuicdn.com/layui-v2.7.6/layui.js"></script>
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
let paySign, appId, timeStamp, nonceStr, packageStr, signType;
layui.use(['form'], function(){
    var form = layui.form, layer = layui.layer;
    form.on('submit(submit)', function(data){
        $.ajax({
            type: "post",
            dataType: "json",
            data: {openId: "{$openid}", score: 100, money: 10},
            url: "/test/recharge",
            async: false,
            success: function(data){
                if(data.code === 0){
                    appId = data.data.appId;
                    paySign = data.data.paySign;
                    timeStamp = data.data.timeStamp;
                    nonceStr = data.data.nonceStr;
                    packageStr = data.data.package;
                    signType = data.data.signType;
                    callpay();
                } else {
                    layer.msg("下单失败请稍后再重试", {time: 50000});
                    return false;
                }
            },
            error: function(){
                layer.alert('系统异常');
            }
        });
        return false;
    });
});

function callpay(){
    if(typeof WeixinJSBridge == "undefined"){
        if(document.addEventListener){
            document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
        } else if(document.attachEvent){
            document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
            document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
        }
    } else {
        onBridgeReady();
    }
}

function onBridgeReady(){
    WeixinJSBridge.invoke('getBrandWCPayRequest', {
        "appId": appId,
        "paySign": paySign,
        "timeStamp": timeStamp,
        "nonceStr": nonceStr,
        "package": packageStr,
        "signType": signType
    }, function(res){
        if(res.err_msg === "get_brand_wcpay_request:ok"){
            window.location.href = 'http://webman.tinywan.com/user/home';
        } else if(res.err_msg === "get_brand_wcpay_request:cancel"){
            window.location.href = 'http://webman.tinywan.com/user/recharge?openid={$openid}';
        } else if(res.err_msg === "get_brand_wcpay_request:fail"){
            window.location.href = 'http://webman.tinywan.com/user/home?openid={$openid}';
        }
    });
}
</script>

Asynchronous Callback (Server Side)

use support\Request;
use Webman\Config;
use Yansongda\Pay\Pay;

public function wechatNotify(Request $request): string
{
    Pay::config(Config::get('payment'));
    $result = Pay::wechat()->callback($request->post());
    $openid = $result['resource']['ciphertext']['payer']['openid'];
    $mchid = $result['resource']['ciphertext']['mchid'];
    $thirdSn = $result['resource']['ciphertext']['transaction_id'];
    $outTradeNo = $result['resource']['ciphertext']['out_trade_no'];
    $tradeState = $result['resource']['ciphertext']['trade_state'];
    $totalAmount = bcdiv((string)$result['resource']['ciphertext']['amount']['total'], '100', 2);
    $success = Pay::wechat()->success()->getBody()->getContents();
    return $success;
}
The callback must be accessed via a POST request.

Logging

All payment‑related logs are stored in runtime/logs/pay.log within the project directory.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PHPAPIWeChat PayPayment IntegrationWebman
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.