小程序端
調用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
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态