首頁 後端開發 php教程 微信支付掃碼支付php版_php實例

微信支付掃碼支付php版_php實例

Aug 04, 2016 am 08:56 AM

本文實例為大家分享了php微信掃碼支付源碼,供大家參考,具體內容如下

程式碼包含四個檔案createUrl.php、ArrayToXML.php、returnGoodsUrl.php、notifyUrl.php

createUrl.php:建立微信二維碼支付連結

<&#63;php
/**
 * @author chantrans
 * 本页面的作用是生成商品二维码链接
 */
//测试
echo createUrl("12314124");

/**
 * 产生随机字符串
 */
function getNonceStr()
{
 $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
 $noceStr = "";
 for ($i = 0; $i < 32; $i++) {
 $noceStr .= $chars[ mt_rand(0, strlen($chars) - 1) ];
 }
 $oldNonceStr = $noceStr;
 return $noceStr;
}
/**
 * 二维码扫码链接构造方式:
 * weixin://wxpay/bizpayurl&#63;sign=XXXXX&appid=XXXXXX&productid=XXXXXX&timestamp=XXXXXX&noncestr=XXXXXX
 *
 appid 是字段名称:公众号id;字段来源:商户注册具有支付权限的公众号成功后即可获得;传入方式:由商户直接传入。
 timestamp 是字段名称:时间戳;字段来源:商户生成从1970 年1 月1 日00:00:00 至今的秒数,即当前的时间;由商户生成后传入。取值范围:32 字符以下
 noncestr 是字段名称:随机字符串;字段来源:商户生成的随机字符串;取值范围:长度为32 个字符以下。由商户生成后传入。取值范围:32 字符以下
 productid 是字段名称:商品唯一id;字段来源:商户需要定义并维护自己的商品id,这个id 与一张订单等价,微信后台凭借该id 通过Post商户后台获取交易必须信息。由商户生成后传入。取值范围:32字符以下
 sign 是字段名称:签名;字段来源:对前面的其他字段与appKey 按照字典序排序后,使用SHA1 算法得到的结果。由商户生成后传入。参与sign 签名的字段包括:appid、timestamp、noncestr、productid 以及appkey。
 */
function createUrl($productid){
 $app_id = "wxbce29784bdd01454"; //公众号appid
 $app_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";//公众号支付请求中用于加密的密钥Key,可验证商户唯一身份,PaySignKey对应于支付场景中的appKey值。
 $nonce_str =getNonceStr();
 $time_stamp = strtotime("now");
 //对所有需要传入的参数加上appkey作一次key=value字典序的排序
 $keyvaluestring = "appid=".$app_id."&appkey=".$app_key."&noncestr=".$nonce_str."&productid=".$productid."&timestamp=".$time_stamp;

 $sign = sha1($keyvaluestring)."";
 $url = "weixin://wxpay/bizpayurl&#63;sign=".$sign."&appid=".$app_id."&productid=".$productid."&timestamp=".$time_stamp."&noncestr=".$nonce_str."";
 return $url;
}
登入後複製

returnGoodsUrl.php:用戶掃描二維碼連結後,微信將連結中的商品ID、openId以及其他資訊post到該腳本,該腳本負責返回與商品ID對應的商品資訊。

<&#63;php
include 'ArrayToXML.php';
header('Content-Type:text/xml');
/***
 * 该脚本为当公众该平台接到Native(原生)支付请求时,会调用此回调URL获取商品信息。
 */

/**
第一步:接收微信服务器post过来的信息
(1)OpenId,点击链接准备购买商品的用户openid
(2)AppId,公众帐号的appid
(3)IsSubscribe,标记用户是否订阅该公众帐号,1 为关注,0 为未关注
(4)ProductId,第三方的商品ID号
(5)TimeStamp,时间戳
(6)NonceStr,随机串
(7)AppSignature,参数的加密签名,是根据2.7 支付签名(paySign)生成方法中所讲的签名方式生成的签名
(8)SignMethod,签名方式,目前只支持“SHA1”。该字段不参与签名
 **/
$postdata = file_get_contents("php://input");
$postObj = simplexml_load_string ( $postdata, 'SimpleXMLElement', LIBXML_NOCDATA );
$openId = $postObj->OpenId;
$AppId = $postObj->AppId;
$IsSubscribe = $postObj->IsSubscribe;
$ProductId = $postObj->ProductId;
$TimeStamp = $postObj->TimeStamp;
$NonceStr = $postObj->NonceStr;
$AppSignature = $postObj->AppSignature;
$SignMethod = $postObj->SignMethod;


/**
 * 第二步,生成订单号,并且和商品信息,用户openID等订单信息保存在数据库中
 * 
 */
function createTradeId(){
 $curDateTime = date("YmdHis");
 //date_default_timezone_set(PRC);
 $strDate = date("Ymd");
 $strTime = date("His");
 //4位随机数
 $randNum = rand(1000, 9999);
 //10位序列号,可以自行调整。
 $strReq = $strTime . $randNum;
 /* 商家的定单号 */
 $mch_vno = $curDateTime . $strReq;
 /********************/
 /*todo 保存订单信息到数据库中*/
 /********************/
 return $mch_vno;
}

/**
 * 第三步:生成商品详情pakage
 * @param string $body 商品描述 
 * @param string $total_fee 订单总金额,单位为分。
 * @param string $out_trade_no 商户系统内部的订单号
 * @return $package
 */
function getPackage($body,$total_fee,$out_trade_no){ 
 $ip=$_SERVER["REMOTE_ADDR"];
 if($ip=="::1"||empty($ip)){
 $ip="127.0.0.1";
 }
 $banktype = "WX";
 $fee_type = "1";//费用类型,这里1为默认的人民币
 $input_charset = "GBK";//字符集,这里将统一使用GBK
 $notify_url = "http://xxxxxx.com/Wxpay/notify.html";//支付成功后将通知该地址
 $out_trade_no =createTradeId();//订单号,商户需要保证该字段对于本商户的唯一性
 $partner = "XXXXXXXX"; //商户号
 $spbill_create_ip =$ip;//订单生成的机器IP
 $partnerKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXX";//这个值和以上其他值不一样是:签名需要它,而最后组成的传输字符串不能含有它。这个key是需要商户好好保存的。
 //首先第一步:对原串进行签名,注意这里不要对任何字段进行编码。这里是将参数按照key=value进行字典排序后组成下面的字符串,在这个字符串最后拼接上key=XXXX。由于这里的字段固定,因此只需要按照这个顺序进行排序即可。
 $signString = "bank_type=".$banktype."&body=".$body."&fee_type=".$fee_type."&input_charset=".$input_charset."&notify_url=".$notify_url."&out_trade_no=".$out_trade_no."&partner=".$partner."&spbill_create_ip=".$spbill_create_ip."&total_fee=".$total_fee."&key=".$partnerKey;
 $md5SignValue = ("" .strtoupper(md5(($signString))));
 //echo $md5SignValue;
 //然后第二步,对每个参数进行url转码。
 $banktype = encodeURIComponent($banktype);
 $body=encodeURIComponent($body);
 $fee_type=encodeURIComponent($fee_type);
 $input_charset = encodeURIComponent($input_charset);
 $notify_url = encodeURIComponent($notify_url);
 $out_trade_no = encodeURIComponent($out_trade_no);
 $partner = encodeURIComponent($partner);
 $spbill_create_ip = encodeURIComponent($spbill_create_ip);
 $total_fee = encodeURIComponent($total_fee);
 
 //然后进行最后一步,这里按照key=value除了sign外进行字典序排序后组成下列的字符串,最后再串接sign=value
 $completeString = "bank_type=".$banktype."&body=".$body."&fee_type=".$fee_type."&input_charset=".$input_charset."&notify_url=".$notify_url."&out_trade_no=".$out_trade_no."&partner=".$partner."&spbill_create_ip=".$spbill_create_ip."&total_fee=".$total_fee;
 $completeString = $completeString."&sign=".$md5SignValue;
 $oldPackageString = $completeString; //记住package,方便最后进行整体签名时取用
 return $completeString;
}

//模拟js中的encodeURIComponent方法
function encodeURIComponent($str) {
 $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
 return strtr(rawurlencode($str), $revert);
}
/**
第四步:
为了返回Package 数据,回调URL 必须返回一个xml 格式的返回数据,形如:
<xml>
<AppId><![CDATA[wwwwb4f85f3a797777]]></AppId>
<Package><![CDATA[a=1&url=http%3A%2F%2Fwww.qq.com]]></Package>
<TimeStamp> 1369745073</TimeStamp>
<NonceStr><![CDATA[iuytxA0cH6PyTAVISB28]]></NonceStr>
<RetCode>0</RetCode>
<RetErrMsg><![CDATA[ok]]></ RetErrMsg>
<AppSignature><![CDATA[53cca9d47b883bd4a5c85a9300df3da0cb48565c]]>
</AppSignature>
<SignMethod><![CDATA[sha1]]></ SignMethod >
</xml>
对于一些第三方觉得商品已经过期或者其他错误的情况,可以在RetCode 和
RetErrMsg 中体现出来,RetCode 为0 表明正确,可以定义其他错误;当定义其他错误时,
可以在RetErrMsg 中填上UTF8 编码的错误提示信息,比如“该商品已经下架”,客户端会
直接提示出来。
 **/

$data=array(
 "AppId"=>$AppId,
 "Package"=>getPackage("测试商品",100,"201311291504302501231"),
 "TimeStamp"=>strtotime(),
 "NonceStr"=>$NonceStr,
 "RetCode"=>0, //RetCode 为0 表明正确,可以定义其他错误;当定义其他错误时,可以在RetErrMsg 中填上UTF8 编码的错误提示信息,比如“该商品已经下架”,客户端会直接提示出来。
 "RetErrMsg"=>"正确返回",
 "AppSignature"=>$AppSignature,
 "SignMethod"=>"sha1"
);
//返回生成的xml数据
echo ArrayToXML::arrtoxml($data);
登入後複製

notifyUrl.php :用戶支付商品後,微信伺服器會將商品信息、支付結果、用戶的openId等重要信息以get和post方式傳遞到該鏈接上,該腳本接收這些信息,並根據支付資訊做出貨處理,最後回傳給微信伺服器success,告知他們,我們已經處理到此通知。否則,微信伺服器將會定期重新發起通知。

<&#63;
/**
后台通知通过请求中的notify_url 进行,采用post 机制。返回通知中的参数一致,url包含如下内容:
见【微信公众号支付】公众号支付接口文档V2.2.pdf 中通知接口部分

同时,在postData 中还将包含xml 数据。数据如下:
<xml>
<OpenId><![CDATA[111222]]></OpenId>
<AppId><![CDATA[wwwwb4f85f3a797777]]></AppId>
<IsSubscribe>1</IsSubscribe>
<TimeStamp> 1369743511</TimeStamp>
<NonceStr><![CDATA[jALldRTHAFd5Tgs5]]></NonceStr>
<AppSignature><![CDATA[bafe07f060f22dcda0bfdb4b5ff756f973aecffa]]>
</AppSignature>
<SignMethod><![CDATA[sha1]]></ SignMethod >
</xml>
商户需要对这些参数进行保存和判断用户的支付状态
*/
// 获取微信通知接口postData信息
$postdata = file_get_contents("php://input"); 
$postObj = simplexml_load_string ( $postdata, 'SimpleXMLElement', LIBXML_NOCDATA );
$trade_state =$_GET ["trade_state"];//支付状态
$out_trade_no = $_GET ["out_trade_no"];//订单号
/*****************  Todo 还有很多其他参数需要保存起来,参数列表详见文档 **************************/
if($trade_state==0){
 echo "success";
}else{
 echo "false";
}

登入後複製

ArrayToXML.php:這個腳本的作用是將陣列轉換成為xml。

<&#63;php

class ArrayToXML
{
 /**
 * @param array $arr
 * @return string XML
 */
 public static function arrtoxml($arr,$dom=0,$item=0)
 {
 if (!$dom){
  $dom = new DOMDocument("1.0");
 }
 if(!$item){
  $item = $dom->createElement("xml"); 
  $dom->appendChild($item);
 }
 foreach ($arr as $key=>$val){
  $itemx = $dom->createElement(is_string($key)&#63;$key:"item");
  $item->appendChild($itemx);
  if (!is_array($val)){
   $text = $dom->createTextNode($val);
   $itemx->appendChild($text);
   
  }else {
   self::arrtoxml($val,$dom,$itemx);
  }
 }
 return $dom->saveXML();
 }
}
登入後複製

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

會話如何劫持工作,如何在PHP中減輕它? 會話如何劫持工作,如何在PHP中減輕它? Apr 06, 2025 am 12:02 AM

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

PHP 8.1中的枚舉(枚舉)是什麼? PHP 8.1中的枚舉(枚舉)是什麼? Apr 03, 2025 am 12:05 AM

PHP8.1中的枚舉功能通過定義命名常量增強了代碼的清晰度和類型安全性。 1)枚舉可以是整數、字符串或對象,提高了代碼可讀性和類型安全性。 2)枚舉基於類,支持面向對象特性,如遍歷和反射。 3)枚舉可用於比較和賦值,確保類型安全。 4)枚舉支持添加方法,實現複雜邏輯。 5)嚴格類型檢查和錯誤處理可避免常見錯誤。 6)枚舉減少魔法值,提升可維護性,但需注意性能優化。

描述紮實的原則及其如何應用於PHP的開發。 描述紮實的原則及其如何應用於PHP的開發。 Apr 03, 2025 am 12:04 AM

SOLID原則在PHP開發中的應用包括:1.單一職責原則(SRP):每個類只負責一個功能。 2.開閉原則(OCP):通過擴展而非修改實現變化。 3.里氏替換原則(LSP):子類可替換基類而不影響程序正確性。 4.接口隔離原則(ISP):使用細粒度接口避免依賴不使用的方法。 5.依賴倒置原則(DIP):高低層次模塊都依賴於抽象,通過依賴注入實現。

在PHPStorm中如何進行CLI模式的調試? 在PHPStorm中如何進行CLI模式的調試? Apr 01, 2025 pm 02:57 PM

在PHPStorm中如何進行CLI模式的調試?在使用PHPStorm進行開發時,有時我們需要在命令行界面(CLI)模式下調試PHP�...

如何用PHP的cURL庫發送包含JSON數據的POST請求? 如何用PHP的cURL庫發送包含JSON數據的POST請求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL庫發送JSON數據在PHP開發中,經常需要與外部API進行交互,其中一種常見的方式是使用cURL庫發送POST�...

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

See all articles