Implementing Paid Reading for WeChat Public Articles Using PHP and WeChat Pay
This tutorial explains how to add a 0.01 CNY paid‑reading button to a WeChat public account article by integrating the WeChat Pay API with PHP, covering the required configuration, the creation of readpay.php and notify.php scripts, and the necessary HTML and JavaScript modifications.
The article demonstrates a simple method to enable paid reading for a WeChat public account article by adding a payment button that unlocks the full content after a successful WeChat Pay transaction.
First, create readpay.php and copy the provided PHP code, replacing placeholders with your merchant ID, AppID, AppSecret, and API key. The script obtains the user's OpenID, creates a unified order, and generates the JavaScript parameters needed for the WeChat JSAPI payment.
<?php
header('Content-type:text/html; Charset=utf-8');
$mchid = '微信支付商户号'; // 微信支付商户号
$appid = '微信支付申请对应的公众号的APPID'; // 微信支付申请对应的公众号的APPID
$appKey = '微信支付申请对应的公众号的APPSECRET'; // 微信支付申请对应的公众号的APPSECRET
$apiKey = 'API密钥'; // 帐户设置-安全设置-API安全-API密钥-设置API密钥
//①、获取用户openid
$wxPay = new WxpayService($mchid,$appid,$appKey,$apiKey);
$openId = $wxPay->GetOpenid(); // 获取openid
if(!$openId) exit('获取openid失败');
//②、统一下单
$outTradeNo = uniqid(); // 你自己的商品订单号
$payAmount = 0.01; // 付款金额,单位:元
$orderName = 'test'; // 订单标题
$notifyUrl = 'nofity.php'; // 付款成功后的回调地址
$payTime = time(); // 付款时间
$jsApiParameters = $wxPay->createJsBizPackage($openId,$payAmount,$outTradeNo,$orderName,$notifyUrl,$payTime);
$jsApiParameters = json_encode($jsApiParameters);
?>
<!--下面就是官方微信文章页面-->
<html>
<head>
<meta charset="utf-8">
<title>新版微信支持双开,王利芬庆祝“茅侃侃去世”文阅读10w+被批人血馒头</title>
<script type="text/javascript">
function jsApiCall(){
WeixinJSBridge.invoke('getBrandWCPayRequest', <?php echo $jsApiParameters; ?>, function(res){
if(res.err_msg == "get_brand_wcpay_request:ok"){
window.location.href="这里填写支付成功后要跳转的查看全文文章地址";
}else{
window.location.href="false.html";
}
});
}
function callpay(){
if(typeof WeixinJSBridge == "undefined"){
if(document.addEventListener){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if(document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}else{
jsApiCall();
}
}
</script>
<style>
#title{margin-bottom:10px;line-height:1.4;font-weight:400;font-size:24px;width:97%;margin:0 auto;}
#meta_content .time{color:#8C8C8C;font-family:"SimHei";}
.author{color:#8C8C8C;font-family:"SimHei";}
.name{color:#607fa6;}
#con{width:95%;font-size:15px;margin:15px auto 25px;color:#595757;}
</style>
</head>
<body>
<h2 id="title">新版微信支持双开,王利芬庆祝“茅侃侃去世”文阅读10w+被批人血馒头</h2>
<div id="meta_content">
<span class="time">2018-01-27</span> <span class="author">tanking</span> <span class="name">里客云</span>
</div>
<div id="con">这一周,公众号议论最多的有…(省略)</div>
<div align="center">
<button style="width:180px;height:35px;background:none;border-radius:5px;border:1px #1AAD19 solid;cursor:pointer;color:#1AAD19;font-size:15px;" type="button" onclick="callpay()">支付0.01阅读全文</button>
</div>
</body>
</html>
<?php
class WxpayService{
protected $mchid;
protected $appid;
protected $appKey;
protected $apiKey;
public $data = null;
public function __construct($mchid,$appid,$appKey,$key){
$this->mchid = $mchid;
$this->appid = $appid;
$this->appKey = $appKey;
$this->apiKey = $key;
}
// ... (methods GetOpenid, createJsBizPackage, curlGet, curlPost, createNonceStr, arrayToXml, getSign, formatQueryParaMap) ...
}
?>Next, create notify.php with the following code, again replacing the merchant ID, AppID, and API key. This script handles the asynchronous callback from WeChat Pay, verifies the signature, and returns a success XML response.
<?php
/**
* 原生支付(扫码支付)及公众号支付的异步回调通知
*/
header('Content-type:text/html; Charset=utf-8');
$mchid = '微信支付商户号';
$appid = '公众号APPID';
$apiKey = 'API密钥';
$wxPay = new WxpayService($mchid,$appid,$apiKey);
$result = $wxPay->notify();
if($result){
// 完成你的逻辑,例如更新订单状态
}else{
echo 'pay error';
}
class WxpayService{
protected $mchid;
protected $appid;
protected $apiKey;
public function __construct($mchid,$appid,$key){
$this->mchid = $mchid;
$this->appid = $appid;
$this->apiKey = $key;
}
public function notify(){
$config = array('mch_id'=>$this->mchid,'appid'=>$this->appid,'key'=>$this->apiKey);
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
$postObj = simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);
if($postObj===false) die('parse xml error');
if($postObj->return_code!='SUCCESS') die($postObj->return_msg);
if($postObj->result_code!='SUCCESS') die($postObj->err_code);
$arr = (array)$postObj;
unset($arr['sign']);
if(self::getSign($arr,$config['key']) == $postObj->sign){
echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
return $arr;
}
}
public static function getSign($params,$key){
ksort($params,SORT_STRING);
$unSignParaString = self::formatQueryParaMap($params,false);
return strtoupper(md5($unSignParaString.'&key='.$key));
}
protected static function formatQueryParaMap($paraMap,$urlEncode=false){
$buff='';
ksort($paraMap);
foreach($paraMap as $k=>$v){
if($v!==null && $v!='null'){
if($urlEncode) $v=urlencode($v);
$buff .= $k.'='.$v.'&';
}
}
return $buff?substr($buff,0,-1):'';
}
}
?>Finally, create a false.html page to display when payment fails, and adjust the redirect URLs in the JavaScript accordingly. Upload all files to the appropriate directory on your server, then access readpay.php to test the paid‑reading flow.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
