微信小程序php后端搭建,php小程序支付notify,PHP 小程序支付

 2023-11-19 阅读 25 评论 0

摘要:小程序端調用wx.requestPayment,所需要的參數都從服務端獲取服務端小程序需要的參數:微信小程序php后端搭建?小程序端需要的參數需要從服務端獲取,這樣簽名才能一致/***?隨機數*?@param?$length*?@param?int?$numericphp yii框架,*?@retur

小程序端

調用wx.requestPayment,所需要的參數都從服務端獲取

服務端小程序需要的參數:

微信小程序php后端搭建?小程序端需要的參數需要從服務端獲取,這樣簽名才能一致/**

*?隨機數

*?@param?$length

*?@param?int?$numeric

php yii框架,*?@return?string

*/

public?function?random($length,?$numeric?=?0)

{

php引用。PHP_VERSION?

$seed?=?base_convert(md5(print_r($_SERVER,?1)?.?microtime()),?16,?$numeric???10?:?35);

$seed?=?$numeric???(str_replace('0',?'',?$seed)?.?'012340567890')?:?($seed?.?'zZ'?.?strtoupper($seed));

$hash?=?'';

小程序支付v2,$max?=?strlen($seed)?-?1;????????for?($i?=?0;?$i?

$hash?.=?$seed[mt_rand(0,?$max)];

}????????return?$hash;

}????public?function?paysing()

支付寶小程序有什么用、{

$appid='';

$key='';//商戶的api密鑰

$nonce_str=$this->random(15);//隨機數,可自己寫個方法生成

小程序支付申請,$prepay_id=$this->post->prepay_id;

$timestamp=time();

$paySign?=?MD5("appId=$appid&nonceStr=$nonce_str&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$timestamp&key=$key");

$json?=?array();

微信支付有優惠小程序。$json['paysign']?=?strtoupper($paySign);

$json['timeStamp']?=?$timestamp.'';

$json['nonceStr']?=?$nonce_str;

$json['package']?='prepay_id='.$prepay_id;????????return?$this->enJson(200,'獲取成功',$json);

個人小程序申請微信支付,}工具類

注意:小程序支付需要額外的參數openid,所以我復制了工具類下單的方法,unifiedOrder2

payapi.php<?phpclass ?wechatAppPay{//接口API?URL前綴

const?API_URL_PREFIX?=?'https://api.mch.weixin.qq.com';//下單地址URL

const?UNIFIEDORDER_URL?=?"/pay/unifiedorder";//查詢訂單URL

const?ORDERQUERY_URL?=?"/pay/orderquery";//關閉訂單URL

const?CLOSEORDER_URL?=?"/pay/closeorder";//公眾賬號ID

private?$appid;//商戶號

private?$mch_id;//隨機字符串

private?$nonce_str;//簽名

private?$sign;//商品描述

private?$body;//商戶訂單號

private?$out_trade_no;//支付總金額

private?$total_fee;//終端IP

private?$spbill_create_ip;//支付結果回調通知地址

private?$notify_url;//交易類型

private?$trade_type;//支付密鑰

private?$key;//證書路徑

private?$SSLCERT_PATH;????private?$SSLKEY_PATH;//所有參數

private?$params?=?array();????public?function?__construct($appid,?$mch_id,?$notify_url,?$key)

{????????$this->appid?=?$appid;????????$this->mch_id?=?$mch_id;????????$this->notify_url?=?$notify_url;????????$this->key?=?$key;

}????/**

*?下單方法

*?@param?$params?下單參數

*/

public?function?unifiedOrder(?$params?){????????$this->body?=?$params['body'];????????$this->out_trade_no?=?$params['out_trade_no'];????????$this->total_fee?=?$params['total_fee'];????????$this->trade_type?=?$params['trade_type'];????????$this->nonce_str?=?$this->genRandomString();????????$this->spbill_create_ip?=?$_SERVER['REMOTE_ADDR'];????????$this->params['appid']?=?$this->appid;????????$this->params['mch_id']?=?$this->mch_id;????????$this->params['nonce_str']?=?$this->nonce_str;????????$this->params['body']?=?$this->body;????????$this->params['out_trade_no']?=?$this->out_trade_no;????????$this->params['total_fee']?=?$this->total_fee;????????$this->params['spbill_create_ip']?=?$this->spbill_create_ip;????????$this->params['notify_url']?=?$this->notify_url;????????$this->params['trade_type']?=?$this->trade_type;//獲取簽名數據

$this->sign?=?$this->MakeSign(?$this->params?);????????$this->params['sign']?=?$this->sign;

$xml?=?$this->data_to_xml($this->params);

$response?=?$this->postXmlCurl($xml,?self::API_URL_PREFIX.self::UNIFIEDORDER_URL);????????if(?!$response?){????????????return?false;

}

$result?=?$this->xml_to_data(?$response?);????????if(?!empty($result['result_code'])?&&?!empty($result['err_code'])?){

$result['err_msg']?=?$this->error_code(?$result['err_code']?);

}????????return?$result;

}????/**

*?小程序?下單方法

*?@param?$params

*?@return?bool|mixed

*/

public?function?unifiedOrder2(?$params?){????????$this->body?=?$params['body'];????????$this->out_trade_no?=?$params['out_trade_no'];????????$this->total_fee?=?$params['total_fee'];????????$this->trade_type?=?$params['trade_type'];????????$this->nonce_str?=?$this->genRandomString();????????$this->spbill_create_ip?=?$_SERVER['REMOTE_ADDR'];????????$this->params['appid']?=?$this->appid;????????$this->params['mch_id']?=?$this->mch_id;????????$this->params['nonce_str']?=?$this->nonce_str;????????$this->params['body']?=?$this->body;????????$this->params['out_trade_no']?=?$this->out_trade_no;????????$this->params['total_fee']?=?$this->total_fee;????????$this->params['spbill_create_ip']?=?$this->spbill_create_ip;????????$this->params['notify_url']?=?$this->notify_url;????????$this->params['trade_type']?=?$this->trade_type;????????$this->params['openid']?=?$params['openid'];//獲取簽名數據

$this->sign?=?$this->MakeSign(?$this->params?);????????$this->params['sign']?=?$this->sign;

$xml?=?$this->data_to_xml($this->params);

$response?=?$this->postXmlCurl($xml,?self::API_URL_PREFIX.self::UNIFIEDORDER_URL);????????if(?!$response?){????????????return?false;

}

$result?=?$this->xml_to_data(?$response?);????????if(?!empty($result['result_code'])?&&?!empty($result['err_code'])?){

$result['err_msg']?=?$this->error_code(?$result['err_code']?);

}????????return?$result;

}????/**

*?查詢訂單信息

*?@param?$out_trade_no?訂單號

*?@return?array

*/

public?function?orderQuery(?$out_trade_no?){????????$this->params['appid']?=?$this->appid;????????$this->params['mch_id']?=?$this->mch_id;????????$this->params['nonce_str']?=?$this->genRandomString();????????$this->params['out_trade_no']?=?$out_trade_no;//獲取簽名數據

$this->sign?=?$this->MakeSign(?$this->params?);????????$this->params['sign']?=?$this->sign;

$xml?=?$this->data_to_xml($this->params);

$response?=?$this->postXmlCurl($xml,?self::API_URL_PREFIX.self::ORDERQUERY_URL);????????if(?!$response?){????????????return?false;

}

$result?=?$this->xml_to_data(?$response?);????????if(?!empty($result['result_code'])?&&?!empty($result['err_code'])?){

$result['err_msg']?=?$this->error_code(?$result['err_code']?);

}????????return?$result;

}????/**

*?關閉訂單

*?@param?$out_trade_no?訂單號

*?@return?array

*/

public?function?closeOrder(?$out_trade_no?){????????$this->params['appid']?=?$this->appid;????????$this->params['mch_id']?=?$this->mch_id;????????$this->params['nonce_str']?=?$this->genRandomString();????????$this->params['out_trade_no']?=?$out_trade_no;//獲取簽名數據

$this->sign?=?$this->MakeSign(?$this->params?);????????$this->params['sign']?=?$this->sign;

$xml?=?$this->data_to_xml($this->params);

$response?=?$this->postXmlCurl($xml,?self::API_URL_PREFIX.self::CLOSEORDER_URL);????????if(?!$response?){????????????return?false;

}

$result?=?$this->xml_to_data(?$response?);????????return?$result;

}????/**

*

*?獲取支付結果通知數據

*?return?array

*/

public?function?getNotifyData(){//獲取通知的數據

$xml?=?$GLOBALS['HTTP_RAW_POST_DATA'];????????//$xml?=?file_get_contents('php://input');

$data?=?array();????????if(?empty($xml)?){????????????return?false;

}

$data?=?$this->xml_to_data(?$xml?);???????if(?!empty($data['return_code'])?){???????????if(?$data['return_code']?==?'FAIL'?){????????????????return?false;

}

}????????return?$data;

}????/**

*?接收通知成功后應答輸出XML數據

*?@param?string?$xml

*/

public?function?replyNotify(){??????/*??ksort($data);

$buff?=?'';

foreach?($data?as?$k?=>?$v){

if($k?!=?'sign'){

$buff?.=?$k?.?'='?.?$v?.?'&';

}

}

$stringSignTemp?=?$buff?.?'key=a1M5s4s6a4r8t4g2h3Md36AlJ8s7f5sd';//key為證書密鑰

$sign?=?strtoupper(md5($stringSignTemp));

//判斷算出的簽名和通知信息的簽名是否一致

if($sign?==?$data['sign']){

//處理完成之后,告訴微信成功結果

echo?'

';

exit();

}

*/

$data['return_code']?=?'SUCCESS';

$data['return_msg']?=?'OK';

$xml?=?$this->data_to_xml(?$data?);????????echo?$xml;????????die();

}????/**

*?生成APP端支付參數

*?@param?$prepayid?預支付id

*/

public?function?getAppPayParams(?$prepayid?){

$data['appid']?=?$this->appid;

$data['partnerid']?=?$this->mch_id;

$data['prepayid']?=?$prepayid;

$data['package']?=?'Sign=WXPay';

$data['noncestr']?=?$this->genRandomString();

$data['timestamp']?=?time();

$data['sign']?=?$this->MakeSign(?$data?);????????return?$data;

}????/**

*?生成簽名

*?@return?簽名

*/

public?function?MakeSign(?$params?){//簽名步驟一:按字典序排序數組參數

ksort($params);

$string?=?$this->ToUrlParams($params);//簽名步驟二:在string后加入KEY

$string?=?$string?.?"&key=".$this->key;//簽名步驟三:MD5加密

$string?=?md5($string);//簽名步驟四:所有字符轉為大寫

$result?=?strtoupper($string);????????return?$result;

}????/**

*?將參數拼接為url:?key=value&key=value

*?@param?$params

*?@return?string

*/

public?function?ToUrlParams(?$params?){

$string?=?'';????????if(?!empty($params)?){

$array?=?array();????????????foreach(?$params?as?$key?=>?$value?){

$array[]?=?$key.'='.$value;

}

$string?=?implode("&",$array);

}????????return?$string;

}????/**

*?輸出xml字符

*?@param?$params?參數名稱

*?return?string?返回組裝的xml

**/

public?function?data_to_xml(?$params?){????????if(!is_array($params)||?count($params)?<=?0)

{????????????return?false;

}

$xml?=?"";????????foreach?($params?as?$key=>$val)

{????????????if?(is_numeric($val)){

$xml.="".$val."".$key.">";

}else{

$xml.="".$key.">";

}

}

$xml.="";????????return?$xml;

}????/**

*?將xml轉為array

*?@param?string?$xml

*?return?array

*/

public?function?xml_to_data($xml){????????if(!$xml){????????????return?false;

}//將XML轉為array//禁止引用外部xml實體

libxml_disable_entity_loader(true);

$data?=?json_decode(json_encode(simplexml_load_string($xml,?'SimpleXMLElement',?LIBXML_NOCDATA)),?true);????????return?$data;

}????/**

*?獲取毫秒級別的時間戳

*/

private?static?function?getMillisecond(){//獲取毫秒的時間戳

$time?=?explode?(?"?",?microtime?()?);

$time?=?$time[1]?.?($time[0]?*?1000);

$time2?=?explode(?".",?$time?);

$time?=?$time2[0];????????return?$time;

}????/**

*?產生一個指定長度的隨機字符串,并返回給用戶

*?@param?type?$len?產生字符串的長度

*?@return?string?隨機字符串

*/

private?function?genRandomString($len?=?32)?{

$chars?=?array(????????????"a",?"b",?"c",?"d",?"e",?"f",?"g",?"h",?"i",?"j",?"k",????????????"l",?"m",?"n",?"o",?"p",?"q",?"r",?"s",?"t",?"u",?"v",????????????"w",?"x",?"y",?"z",?"A",?"B",?"C",?"D",?"E",?"F",?"G",????????????"H",?"I",?"J",?"K",?"L",?"M",?"N",?"O",?"P",?"Q",?"R",????????????"S",?"T",?"U",?"V",?"W",?"X",?"Y",?"Z",?"0",?"1",?"2",????????????"3",?"4",?"5",?"6",?"7",?"8",?"9"

);

$charsLen?=?count($chars)?-?1;//?將數組打亂

shuffle($chars);

$output?=?"";????????for?($i?=?0;?$i?

$output?.=?$chars[mt_rand(0,?$charsLen)];

}????????return?$output;

}????/**

*?以post方式提交xml到對應的接口url

*

*?@param?string?$xml?需要post的xml數據

*?@param?string?$url?url

*?@param?bool?$useCert?是否需要證書,默認不需要

*?@param?int?$second?url執行超時時間,默認30s

*?@throws?WxPayException

*/

private?function?postXmlCurl($xml,?$url,?$useCert?=?false,?$second?=?30){

$ch?=?curl_init();//設置超時

curl_setopt($ch,?CURLOPT_TIMEOUT,?$second);

curl_setopt($ch,CURLOPT_URL,?$url);

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);

curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//設置header

curl_setopt($ch,?CURLOPT_HEADER,?FALSE);//要求結果為字符串且輸出到屏幕上

curl_setopt($ch,?CURLOPT_RETURNTRANSFER,?TRUE);????????if($useCert?==?true){//設置證書//使用證書:cert?與?key?分別屬于兩個.pem文件

curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');//curl_setopt($ch,CURLOPT_SSLCERT,?WxPayConfig::SSLCERT_PATH);

curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');//curl_setopt($ch,CURLOPT_SSLKEY,?WxPayConfig::SSLKEY_PATH);

}//post提交方式

curl_setopt($ch,?CURLOPT_POST,?TRUE);

curl_setopt($ch,?CURLOPT_POSTFIELDS,?$xml);//運行curl

$data?=?curl_exec($ch);//返回結果

if($data){

curl_close($ch);????????????return?$data;

}?else?{

$error?=?curl_errno($ch);

curl_close($ch);????????????return?false;

}

}????/**

*?錯誤代碼

*?@param?$code?服務器輸出的錯誤代碼

*?return?string

*/

public?function?error_code(?$code?){

$errList?=?array(????????????'NOAUTH'?=>?'商戶未開通此接口權限',????????????'NOTENOUGH'?=>?'用戶帳號余額不足',????????????'ORDERNOTEXIST'?=>?'訂單號不存在',????????????'ORDERPAID'?=>?'商戶訂單已支付,無需重復操作',????????????'ORDERCLOSED'?=>?'當前訂單已關閉,無法支付',????????????'SYSTEMERROR'?=>?'系統錯誤!系統超時',????????????'APPID_NOT_EXIST'?=>?'參數中缺少APPID',????????????'MCHID_NOT_EXIST'?=>?'參數中缺少MCHID',????????????'APPID_MCHID_NOT_MATCH'?=>?'appid和mch_id不匹配',????????????'LACK_PARAMS'?=>?'缺少必要的請求參數',????????????'OUT_TRADE_NO_USED'?=>?'同一筆交易不能多次提交',????????????'SIGNERROR'?=>?'參數簽名結果不正確',????????????'XML_FORMAT_ERROR'?=>?'XML格式錯誤',????????????'REQUIRE_POST_METHOD'?=>?'未使用post傳遞參數?',????????????'POST_DATA_EMPTY'?=>?'post數據不能為空',????????????'NOT_UTF8'?=>?'未使用指定編碼格式',

);????????if(?array_key_exists(?$code?,?$errList?)?){????????????return?$errList[$code];

}

}

}

統一下單include_once?"payapi.php";

$params['body']?=?$bodys;?//商品描述

$params['out_trade_no']?=?$order;?//自定義的訂單號

$params['total_fee']?=?$allmoney*100;?//訂單金額?只能為整數?單位為分

$params['trade_type']?=?'JSAPI';?//交易類型?JSAPI?|?NATIVE?|?APP?|?WAP

$params['openid']?=?‘22222222’;//微信用戶的openid

$PAYAPPID?=?$pay->appid;

$PAYKEY?=?'xxxx';//商戶密鑰

$PAYMCHID?=?'xxxxx';//商戶id

$NOTIFY_URL?=?'http://xxxxx';//這里只需填寫你網址即可

$wechatAppPay?=?new?wechatAppPay($PAYAPPID,?$PAYMCHID,?$NOTIFY_URL,?$PAYKEY);

$result?=?$wechatAppPay->unifiedOrder2(?$params?);????????if?($result['result_code']=='SUCCESS'&&$result['return_code']=='SUCCESS')?{????????//下單成功,記錄在庫處理邏輯

//..............

//....................

//返回訂單號,后面小程序拿來查詢訂單的狀態的

result['out_trade_no']?=?$order;????????return?$this->enJson(200,?'下單成功',?$result);

}小程序支付成功后調用查詢訂單接口,修改訂單狀態://查詢訂單狀態

$PAYAPPID?=?$appid;

$PAYKEY?=?$paykey;

$PAYMCHID?=?$mch_id;

$NOTIFY_URL?=?'https://www.xxxxx';

$out_trade_no=$_POST['out_trade_no'];//自定義的訂單號

$openid?=$_POST['openid'];

$wechatAppPay?=?new?wechatAppPay($PAYAPPID,?$PAYMCHID,?$NOTIFY_URL,?$PAYKEY);

$res=$wechatAppPay->orderQuery($out_trade_no);????????if?($res['return_code']=='SUCCESS'&&$res['result_code']=='SUCCESS'&&$res['trade_state']=='SUCCESS'){????????//支付成功,修改訂單狀態}

基本的流程差不多就是這個樣子了,如果哪里不對或不明確歡迎留言

作者:心之所善兮

鏈接:https://www.jianshu.com/p/8d1ac4123aab

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/182286.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息