摘要:本文分享原生支付模式一,供技術員參考學習。官網地址模式一商戶按固定格式生成鏈接二維碼,用戶掃碼后調微信會將和用戶發送到商戶設置的鏈接上,商戶收到請求生成訂單,調用統一支付接口下單提交到微信,微信會返回給商戶。
wemall-mobile是基于WeMall的Android app商城,只需要在原商城目錄下上傳接口文件即可完成服務端的配置,客戶端可定制修改。本文分享Native(原生)支付模式一demo,供技術員參考學習。
wemall官網地址:http://www.wemallshop.com
模式一:商戶按固定格式生成鏈接二維碼,用戶掃碼后調微信
會將productid和用戶openid發送到商戶設置的鏈接上,商戶收到
請求生成訂單,調用統一支付接口下單提交到微信,微信會返回
給商戶prepayid。
本例程對應的二維碼由native_call_qrcode.php生成;
本例程對應的響應服務為native_call.php;
需要兩者配合使用。
native_call.php
log_result($log_name,"【接收到的native通知】:
".$xml."
");
$nativeCall->saveData($xml);
if($nativeCall->checkSign() == FALSE){
$nativeCall->setReturnParameter("return_code","FAIL");//返回狀態碼
$nativeCall->setReturnParameter("return_msg","簽名失敗");//返回信息
}else{
//提取product_id
$product_id = $nativeCall->getProductId();
//使用統一支付接口
$unifiedOrder = new UnifiedOrder_pub();
//根據不同的$product_id設定對應的下單參數,此處只舉例一種
switch ($product_id)
{
case WxPayConf_pub::APPID."static"://與native_call_qrcode.php中的靜態鏈接二維碼對應
//設置統一支付接口參數
//設置必填參數
//appid已填,商戶無需重復填寫
//mch_id已填,商戶無需重復填寫
//noncestr已填,商戶無需重復填寫
//spbill_create_ip已填,商戶無需重復填寫
//sign已填,商戶無需重復填寫
$unifiedOrder->setParameter("body","貢獻一分錢");//商品描述
//自定義訂單號,此處僅作舉例
$timeStamp = time();
$out_trade_no = WxPayConf_pub::APPID."$timeStamp";
$unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商戶訂單號 $unifiedOrder->setParameter("product_id","$product_id");//商品ID
$unifiedOrder->setParameter("total_fee","1");//總金額
$unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址
$unifiedOrder->setParameter("trade_type","NATIVE");//交易類型
$unifiedOrder->setParameter("product_id","$product_id");//用戶標識
//非必填參數,商戶可根據實際情況選填
//$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商戶號
//$unifiedOrder->setParameter("device_info","XXXX");//設備號
//$unifiedOrder->setParameter("attach","XXXX");//附加數據
//$unifiedOrder->setParameter("time_start","XXXX");//交易起始時間
//$unifiedOrder->setParameter("time_expire","XXXX");//交易結束時間
//$unifiedOrder->setParameter("goods_tag","XXXX");//商品標記
//$unifiedOrder->setParameter("openid","XXXX");//用戶標識
//獲取prepay_id
$prepay_id = $unifiedOrder->getPrepayId();
//設置返回碼
//設置必填參數
//appid已填,商戶無需重復填寫
//mch_id已填,商戶無需重復填寫
//noncestr已填,商戶無需重復填寫
//sign已填,商戶無需重復填寫
$nativeCall->setReturnParameter("return_code","SUCCESS");//返回狀態碼
$nativeCall->setReturnParameter("result_code","SUCCESS");//業務結果
$nativeCall->setReturnParameter("prepay_id","$prepay_id");//預支付ID
break;
default:
//設置返回碼
//設置必填參數
//appid已填,商戶無需重復填寫
//mch_id已填,商戶無需重復填寫
//noncestr已填,商戶無需重復填寫
//sign已填,商戶無需重復填寫
$nativeCall->setReturnParameter("return_code","SUCCESS");//返回狀態碼
$nativeCall->setReturnParameter("result_code","FAIL");//業務結果
$nativeCall->setReturnParameter("err_code_des","此商品無效");//業務結果
break;
}
}
//將結果返回微信
$returnXml = $nativeCall->returnXml();
$log_->log_result($log_name,"【返回微信的native響應】:
".$returnXml."
");
echo $returnXml;
//交易完成
?>
log_.php
WxPayPubHelper.php
$v)
{
if($urlencode)
{
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar;
if (strlen($buff) > 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
}
/**
* 作用:生成簽名
*/
public function getSign($Obj)
{
foreach ($Obj as $k => $v)
{
$Parameters[$k] = $v;
}
//簽名步驟一:按字典序排序參數
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//echo "【string1】".$String."";
//簽名步驟二:在string后加入KEY
$String = $String."&key=".WxPayConf_pub::KEY;
//echo "【string2】".$String."";
//簽名步驟三:MD5加密
$String = md5($String);
//echo "【string3】 ".$String."";
//簽名步驟四:所有字符轉為大寫
$result_ = strtoupper($String);
//echo "【result】 ".$result_."";
return $result_;
}
/**
* 作用:array轉xml
*/
function arrayToXml($arr)
{
$xml = "";
foreach ($arr as $key=>$val)
{
if (is_numeric($val))
{
$xml.="<".$key.">".$val."".$key.">";
}
else
$xml.="<".$key.">".$key.">";
}
$xml.="";
return $xml;
}
/**
* 作用:將xml轉為array
*/
public function xmlToArray($xml)
{
//將XML轉為array
$array_data = json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true);
return $array_data;
}
/**
* 作用:以post方式提交xml到對應的接口url
*/
public function postXmlCurl($xml,$url,$second=30)
{
//初始化curl
$ch = curl_init();
//設置超時
curl_setopt($ch, CURLOP_TIMEOUT, $second);
//這里設置代理,如果有的話
//curl_setopt($ch,CURLOPT_PROXY, "8.8.8.8");
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
//設置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求結果為字符串且輸出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//運行curl
$data = curl_exec($ch);
curl_close($ch);
//返回結果
if($data)
{
curl_close($ch);
return $data;
}
else
{
$error = curl_errno($ch);
echo "curl出錯,錯誤碼:$error"."
";
echo "";
echo "");
echo $wording."";
var_dump($err);
print_r("
");
}
}
/**
* 請求型接口的基類
*/
class Wxpay_client_pub extends Common_util_pub
{
var $parameters;//請求參數,類型為關聯數組
public $response;//微信返回的響應
public $result;//返回參數,類型為關聯數組
var $url;//接口鏈接
var $curl_timeout;//curl超時時間
/**
* 作用:設置請求參數
*/
function setParameter($parameter, $parameterValue)
{
$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
}
/**
* 作用:設置標配的請求參數,生成簽名,生成接口參數xml
*/
function createXml()
{
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}
/**
* 作用:post請求xml
*/
function postXml()
{
$xml = $this->createXml();
$this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout);
return $this->response;
}
/**
* 作用:使用證書post請求xml
*/
function postXmlSSL()
{
$xml = $this->createXml();
$this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout);
return $this->response;
}
/**
* 作用:獲取結果,默認不使用證書
*/
function getResult()
{
$this->postXml();
$this->result = $this->xmlToArray($this->response);
return $this->result;
}
}
/**
* 統一支付接口類
*/
class UnifiedOrder_pub extends Wxpay_client_pub
{
function __construct()
{
//設置接口鏈接
$this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 生成接口參數xml
*/
function createXml()
{
try
{
//檢測必填參數
if($this->parameters["out_trade_no"] == null)
{
throw new SDKRuntimeException("缺少統一支付接口必填參數out_trade_no!"."
");
}elseif($this->parameters["body"] == null){
throw new SDKRuntimeException("缺少統一支付接口必填參數body!"."
");
}elseif ($this->parameters["total_fee"] == null ) {
throw new SDKRuntimeException("缺少統一支付接口必填參數total_fee!"."
");
}elseif ($this->parameters["notify_url"] == null) {
throw new SDKRuntimeException("缺少統一支付接口必填參數notify_url!"."
");
}elseif ($this->parameters["trade_type"] == null) {
throw new SDKRuntimeException("缺少統一支付接口必填參數trade_type!"."
");
}elseif ($this->parameters["trade_type"] == "JSAPI" &&
$this->parameters["openid"] == NULL){
throw new SDKRuntimeException("統一支付接口中,缺少必填參數openid!trade_type為JSAPI時,openid為必填參數!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["spbill_create_ip"] = $_SERVER["REMOTE_ADDR"];//終端ip
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
/**
* 獲取prepay_id
*/
function getPrepayId()
{
$this->postXml();
$this->result = $this->xmlToArray($this->response);
$prepay_id = $this->result["prepay_id"];
return $prepay_id;
}
}
/**
* 訂單查詢接口
*/
class OrderQuery_pub extends Wxpay_client_pub
{
function __construct()
{
//設置接口鏈接
$this->url = "https://api.mch.weixin.qq.com/pay/orderquery";
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 生成接口參數xml
*/
function createXml()
{
try
{
//檢測必填參數
if($this->parameters["out_trade_no"] == null &&
$this->parameters["transaction_id"] == null)
{
throw new SDKRuntimeException("訂單查詢接口中,out_trade_no、transaction_id至少填一個!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
}
/**
* 退款申請接口
*/
class Refund_pub extends Wxpay_client_pub
{
function __construct() {
//設置接口鏈接
$this->url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 生成接口參數xml
*/
function createXml()
{
try
{
//檢測必填參數
if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) {
throw new SDKRuntimeException("退款申請接口中,out_trade_no、transaction_id至少填一個!"."
");
}elseif($this->parameters["out_refund_no"] == null){
throw new SDKRuntimeException("退款申請接口中,缺少必填參數out_refund_no!"."
");
}elseif($this->parameters["total_fee"] == null){
throw new SDKRuntimeException("退款申請接口中,缺少必填參數total_fee!"."
");
}elseif($this->parameters["refund_fee"] == null){
throw new SDKRuntimeException("退款申請接口中,缺少必填參數refund_fee!"."
");
}elseif($this->parameters["op_user_id"] == null){
throw new SDKRuntimeException("退款申請接口中,缺少必填參數op_user_id!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
/**
* 作用:獲取結果,使用證書通信
*/
function getResult()
{
$this->postXmlSSL();
$this->result = $this->xmlToArray($this->response);
return $this->result;
}
}
/**
* 退款查詢接口
*/
class RefundQuery_pub extends Wxpay_client_pub
{
function __construct() {
//設置接口鏈接
$this->url = "https://api.mch.weixin.qq.com/pay/refundquery";
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 生成接口參數xml
*/
function createXml()
{
try
{
if($this->parameters["out_refund_no"] == null &&
$this->parameters["out_trade_no"] == null &&
$this->parameters["transaction_id"] == null &&
$this->parameters["refund_id "] == null)
{
throw new SDKRuntimeException("退款查詢接口中,out_refund_no、out_trade_no、transaction_id、refund_id四個參數必填一個!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
/**
* 作用:獲取結果,使用證書通信
*/
function getResult()
{
$this->postXmlSSL();
$this->result = $this->xmlToArray($this->response);
return $this->result;
}
}
/**
* 對賬單接口
*/
class DownloadBill_pub extends Wxpay_client_pub
{
function __construct()
{
//設置接口鏈接
$this->url = "https://api.mch.weixin.qq.com/pay/downloadbill";
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 生成接口參數xml
*/
function createXml()
{
try
{
if($this->parameters["bill_date"] == null )
{
throw new SDKRuntimeException("對賬單接口中,缺少必填參數bill_date!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
/**
* 作用:獲取結果,默認不使用證書
*/
function getResult()
{
$this->postXml();
$this->result = $this->xmlToArray($this->result_xml);
return $this->result;
}
}
/**
* 短鏈接轉換接口
*/
class ShortUrl_pub extends Wxpay_client_pub
{
function __construct()
{
//設置接口鏈接
$this->url = "https://api.mch.weixin.qq.com/tools/shorturl";
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 生成接口參數xml
*/
function createXml()
{
try
{
if($this->parameters["long_url"] == null )
{
throw new SDKRuntimeException("短鏈接轉換接口中,缺少必填參數long_url!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
return $this->arrayToXml($this->parameters);
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
/**
* 獲取prepay_id
*/
function getShortUrl()
{
$this->postXml();
$prepay_id = $this->result["short_url"];
return $prepay_id;
}
}
/**
* 響應型接口基類
*/
class Wxpay_server_pub extends Common_util_pub
{
public $data;//接收到的數據,類型為關聯數組
var $returnParameters;//返回參數,類型為關聯數組
/**
* 將微信的請求xml轉換成關聯數組,以方便數據處理
*/
function saveData($xml)
{
$this->data = $this->xmlToArray($xml);
}
function checkSign()
{
$tmpData = $this->data;
unset($tmpData["sign"]);
$sign = $this->getSign($tmpData);//本地簽名
if ($this->data["sign"] == $sign) {
return TRUE;
}
return FALSE;
}
/**
* 獲取微信的請求數據
*/
function getData()
{
return $this->data;
}
/**
* 設置返回微信的xml數據
*/
function setReturnParameter($parameter, $parameterValue)
{
$this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
}
/**
* 生成接口參數xml
*/
function createXml()
{
return $this->arrayToXml($this->returnParameters);
}
/**
* 將xml數據返回微信
*/
function returnXml()
{
$returnXml = $this->createXml();
return $returnXml;
}
}
/**
* 通用通知接口
*/
class Notify_pub extends Wxpay_server_pub
{
}
/**
* 請求商家獲取商品信息接口
*/
class NativeCall_pub extends Wxpay_server_pub
{
/**
* 生成接口參數xml
*/
function createXml()
{
if($this->returnParameters["return_code"] == "SUCCESS"){
$this->returnParameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->returnParameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$this->returnParameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->returnParameters["sign"] = $this->getSign($this->returnParameters);//簽名
}
return $this->arrayToXml($this->returnParameters);
}
/**
* 獲取product_id
*/
function getProductId()
{
$product_id = $this->data["product_id"];
return $product_id;
}
}
/**
* 靜態鏈接二維碼
*/
class NativeLink_pub extends Common_util_pub
{
var $parameters;//靜態鏈接參數
var $url;//靜態鏈接
function __construct()
{
}
/**
* 設置參數
*/
function setParameter($parameter, $parameterValue)
{
$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
}
/**
* 生成Native支付鏈接二維碼
*/
function createLink()
{
try
{
if($this->parameters["product_id"] == null)
{
throw new SDKRuntimeException("缺少Native支付二維碼鏈接必填參數product_id!"."
");
}
$this->parameters["appid"] = WxPayConf_pub::APPID;//公眾賬號ID
$this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商戶號
$time_stamp = time();
$this->parameters["time_stamp"] = "$time_stamp";//時間戳
$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串
$this->parameters["sign"] = $this->getSign($this->parameters);//簽名
$bizString = $this->formatBizQueryParaMap($this->parameters, false);
$this->url = "weixin://wxpay/bizpayurl?".$bizString;
}catch (SDKRuntimeException $e)
{
die($e->errorMessage());
}
}
/**
* 返回鏈接
*/
function getUrl()
{
$this->createLink();
return $this->url;
}
}
/**
* JSAPI支付——H5網頁端調起支付接口
*/
class JsApi_pub extends Common_util_pub
{
var $code;//code碼,用以獲取openid
var $openid;//用戶的openid
var $parameters;//jsapi參數,格式為json
var $prepay_id;//使用統一支付接口得到的預支付id
var $curl_timeout;//curl超時時間
function __construct()
{
//設置curl超時時間
$this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;
}
/**
* 作用:生成可以獲得code的url
*/
function createOauthUrlForCode($redirectUrl)
{
$urlObj["appid"] = WxPayConf_pub::APPID;
$urlObj["redirect_uri"] = "$redirectUrl";
$urlObj["response_type"] = "code";
$urlObj["scope"] = "snsapi_base";
$urlObj["state"] = "STATE"."#wechat_redirect";
$bizString = $this->formatBizQueryParaMap($urlObj, false);
return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
}
/**
* 作用:生成可以獲得openid的url
*/
function createOauthUrlForOpenid()
{
$urlObj["appid"] = WxPayConf_pub::APPID;
$urlObj["secret"] = WxPayConf_pub::APPSECRET;
$urlObj["code"] = $this->code;
$urlObj["grant_type"] = "authorization_code";
$bizString = $this->formatBizQueryParaMap($urlObj, false);
return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
}
/**
* 作用:通過curl向微信提交code,以獲取openid
*/
function getOpenid()
{
$url = $this->createOauthUrlForOpenid();
//初始化curl
$ch = curl_init();
//設置超時
curl_setopt($ch, CURLOP_TIMEOUT, $this->curl_timeout);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//運行curl,結果以jason形式返回
$res = curl_exec($ch);
curl_close($ch);
//取出openid
$data = json_decode($res,true);
$this->openid = $data["openid"];
return $this->openid;
}
/**
* 作用:設置prepay_id
*/
function setPrepayId($prepayId)
{
$this->prepay_id = $prepayId;
}
/**
* 作用:設置code
*/
function setCode($code_)
{
$this->code = $code_;
}
/**
* 作用:設置jsapi的參數
*/
public function getParameters()
{
$jsApiObj["appId"] = WxPayConf_pub::APPID;
$timeStamp = time();
$jsApiObj["timeStamp"] = "$timeStamp";
$jsApiObj["nonceStr"] = $this->createNoncestr();
$jsApiObj["package"] = "prepay_id=$this->prepay_id";
$jsApiObj["signType"] = "MD5";
$jsApiObj["paySign"] = $this->getSign($jsApiObj);
$this->parameters = json_encode($jsApiObj);
return $this->parameters;
}
}
?>
WeMall - 開源微商城 微信商城 商城源碼 分銷商城 b2b2c商城系統
wemall官網地址:http://www.wemallshop.com