1符匾、微支付
準(zhǔn)備工作
1.1 在微信開(kāi)放平臺(tái)(https://open.weixin.qq.com)注冊(cè)并認(rèn)證成為開(kāi)發(fā)者賬號(hào)
1.2 在移動(dòng)應(yīng)用內(nèi)創(chuàng)建移動(dòng)應(yīng)用,審核通過(guò)后獲取到該應(yīng)用的AppID和AppSecret
1.3 點(diǎn)擊微支付后面的申請(qǐng)進(jìn)入微支付申請(qǐng)流程瘩例,這里分為已有微商戶和沒(méi)有微商戶兩種啊胶,沒(méi)有微商戶的直接申請(qǐng)即可;已有微商戶的需要進(jìn)行APPID授權(quán)(產(chǎn)品中心→APP支付→appid授權(quán))垛贤,進(jìn)行授權(quán)以后說(shuō)明這個(gè)app就可以調(diào)用app支付了;
1.4 HBuilderX manifest.json文件配置APP SDK選項(xiàng)勾選微信支付焰坪,填入微信開(kāi)放平臺(tái)獲取到的appid;
1.5 準(zhǔn)備后端代碼聘惦,這里我使用的是thinkphp5.0作為后端api接口關(guān)鍵控制器如下
<?php
namespace app\api\controller;
use app\common\model\Wxpaylog;
use xcxwxpay\database\WxPayUnifiedOrder;
use xcxwxpay\database\WxPayTransferPayment;
use xcxwxpay\WxPayApi;
use app\api\common\orderlogic;
use xcxwxpay\database\WxPayResults;
use xcxwxpay\WxPayConfig;
class Wxapppay extends Filter{
public function index(){
$action = input("get.a","");
switch ($action){
case "payinfo":
$oid = input("post.oid",-1);
if(empty($oid)||$oid==""||!is_numeric($oid)||$oid==-1) $this->apireturn(0,"invalid oid");
$result = $this->payinfo($oid);
if($result["errors"]!="") $this->apireturn(0,$result["errors"]);
$ostring = $result["orderstring"];
$this->apireturn(1,"請(qǐng)求成功",$ostring);
break;
default:
$this->apireturn(0,"invalid action");
break;
}
}
private function payinfo($oid){
$orderlogic = new orderlogic();
$info = $orderlogic->getOrderInfo($oid);
// 統(tǒng)一下單獲取預(yù)支付訂單信息
$response = $this->getOrderstring("你app的名稱-訂單支付",$info["number"],$info["paymoney"]["values"]);
// 生成調(diào)起支付請(qǐng)求的參數(shù)
$input = new WxPayTransferPayment();
$input->setPrepayId($response["prepay_id"]);
if(!$input->isPrepayIdSet()){
return ["errors"=>"缺少調(diào)起支付必填參數(shù)prepayid"];
}
$input->setAppid(WxPayConfig::$APPID);
$input->setPartnerId(WxPayConfig::$MCHID);
$input->setPackage("Sign=WXPay");
$input->setNonceStr(self::getNonceStr());//隨機(jī)字符串
$input->setTimeStamt(time());
$arr = array(
"appid" => $input->getAppid(),
"partnerid"=>$input->getPartnerId(),
"prepayid"=>$input->getPrepayId(),
"package"=>"Sign=WXPay",
"noncestr"=>$input->getNonceStr(),
"timestamp" => $input->getTimeStamt(),
);
$sign = $this->makeSign($arr);
$data = array(
"appid" => $input->getAppid(),
"partnerid"=>$input->getPartnerId(),
"prepayid"=>$input->getPrepayId(),
"package"=>"Sign=WXPay",
"noncestr"=>$input->getNonceStr(),
"timestamp" => $input->getTimeStamt(),
"paySign" => $sign
);
return ["errors"=>"","orderstring"=>$data];
}
// 統(tǒng)一下單
private function getOrderstring($body,$out_trade_no,$total_amount)
{
//統(tǒng)一下單
$money = $total_amount;
$money = 0.01;
$input = new WxPayUnifiedOrder();
$input->setBody($body);
$input->setAttach("");
$input->setOutTradeNo($out_trade_no);
$input->setTotalFee($money * 100);
$input->setTimeStart(date("YmdHis"));
$input->setTimeExpire(date("YmdHis", time() + 3*24*60*60));
$input->setNotifyUrl("https://xxxxxxx.com/api/wxapppay/notify.html");
$input->setTradeType("APP");
$order = WxPayApi::unifiedOrder($input);
return $order;
}
public function notify()
{
$xml = file_get_contents("php://input");
$result = WxPayResults::Init($xml);
Writef("wxpaylog.txt",$xml);
if($result["result_code"]=="SUCCESS"){
$ordernumber = $result["out_trade_no"];
$paytime = formateTimeStamp(time());
$orderlogic = new orderlogic();
$orderlogic->payOrder($ordernumber,$paytime,"微支付");
$arr = array("return_code"=>"SUCCESS","return_msg"=>"OK");
echo $this->toXml($arr);
}
$this->writepaylog($result);
}
private function writepaylog($result){
$wxlog = new Wxpaylog();
$wxlog["appid"] = $result["appid"];
$wxlog["bank_type"] = $result["bank_type"];
$wxlog["cash_fee"] = $result["cash_fee"];
$wxlog["fee_type"] = $result["fee_type"];
$wxlog["is_subscribe"] = $result["is_subscribe"];
$wxlog["mch_id"] = $result["mch_id"];
$wxlog["nonce_str"] = $result["nonce_str"];
$wxlog["openid"] = $result["openid"];
$wxlog["out_trade_no"] = $result["out_trade_no"];
$wxlog["result_code"] = $result["result_code"];
$wxlog["return_code"] = $result["return_code"];
$wxlog["sign"] = $result["sign"];
$wxlog["time_end"] = $result["time_end"];
$wxlog["total_fee"] = $result["total_fee"];
$wxlog["trade_type"] = $result["trade_type"];
$wxlog["transaction_id"] = $result["transaction_id"];
$wxlog->save();
}
/**
* 輸出xml字符
**/
private function toXml($arr)
{
if (!is_array($arr)
|| count($arr) <= 0
) {
return "";
}
$xml = "<xml>";
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
/**
* 格式化參數(shù)格式化成url參數(shù)
*/
private function toUrlParams($arr)
{
$buff = "";
foreach ($arr as $k => $v) {
if ($k != "sign" && $v != "" && !is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 生成簽名
* @return string 簽名某饰,本函數(shù)不覆蓋sign成員變量,如要設(shè)置簽名需要調(diào)用setSign方法賦值
*/
private function makeSign($arr)
{
//簽名步驟一:按字典序排序參數(shù)
ksort($arr);
$string = $this->toUrlParams($arr);
//簽名步驟二:在string后加入KEY
$string = $string . "&key=" . WxPayConfig::$KEY;
//簽名步驟三:MD5加密
$string = md5($string);
//簽名步驟四:所有字符轉(zhuǎn)為大寫(xiě)
$result = strtoupper($string);
return $result;
}
/**
*
* 產(chǎn)生隨機(jī)字符串善绎,不長(zhǎng)于32位
* @param int $length
* @return string 產(chǎn)生的隨機(jī)字符串
*/
private static function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
}
1.6 前端uni-app代碼如下,點(diǎn)擊支付后執(zhí)行如下代碼
var uri = "Wxapppay/index.html?a=payinfo";
var param = {oid:that.orderinfo.oid};
that.$post(uri,param,"POST",function(res){
var jsondata = res.data;
//console.log(JSON.stringify(jsondata));
if(jsondata.code==1){
var orderinfo = jsondata.data;
if(orderinfo){
uni.requestPayment({
provider:"wxpay",
timeStamp:orderinfo.timestamp,
nonceStr:orderinfo.noncestr,
package:orderinfo.package,
signType:"MD5",
paySign:orderinfo.paySign,
orderInfo:{
appid:orderinfo.appid,
noncestr:orderinfo.noncestr,
package:"Sign=WXPay",
partnerid:orderinfo.partnerid,
prepayid:orderinfo.prepayid,
timestamp:orderinfo.timestamp,
sign:orderinfo.paySign,
},
success:function(res){
uni.showToast({
title:"支付成功",
icon:"success",
duration:2000,
complete:function(){
uni.reLaunch({
url:"showresult?paytype=1"
});
}
});
},
fail:function(res){
// console.log(JSON.stringify(res));
uni.showToast({
title: '支付失敗黔漂,請(qǐng)到訂單中心重新支付',
icon: "none",
duration: 2000,
complete: function () {
wx.reLaunch({
url: 'showresult?paytype=3',
});
}
});
}
});
}
}else{
}
},function(){},function(){});
注意 注意 注意:如果是默認(rèn)基座的話會(huì)提示:HBuilder mainifest.json中配置的支付appid和生成訂單使用的appid不一致,如果是HB調(diào)試請(qǐng)?jiān)诰€打包,http://ask.dcloud.net.cn/article/282",必須使用自定義基座才能真機(jī)調(diào)試支付
2禀酱、支付寶支付
準(zhǔn)備工作
1.1 在支付寶平臺(tái)注冊(cè)商戶用戶
1.2 在支付寶商戶后臺(tái)產(chǎn)品中心簽約app支付
1.3 在螞蟻金服開(kāi)放平臺(tái)(https://open.alipay.com)開(kāi)發(fā)中心→網(wǎng)頁(yè)和移動(dòng)應(yīng)用 新增app應(yīng)用炬守,通過(guò)以后設(shè)置好應(yīng)用公鑰,系統(tǒng)會(huì)自動(dòng)生成支付寶公鑰 注意新增的時(shí)候 iOS bundle ID一定要填寫(xiě)正確
1.4 HBuilder mainifest.json中設(shè)置支付寶ios scheme用于支付完成跳轉(zhuǎn)回應(yīng)用比勉。
1.5 后臺(tái)代碼參考支付寶示例代碼
<?php
namespace app\api\controller;
use app\api\common\orderlogic;
class Alipay extends Filter{
public function index(){
$action = input("get.a","");
switch ($action){
case "payinfo":
$oid = input("post.oid",-1);
if(empty($oid)||$oid==""||!is_numeric($oid)||$oid==-1) $this->apireturn(0,"invalid oid");
$result = $this->payinfo($oid);
$this->apireturn(1,"請(qǐng)求成功",$result);
break;
default:
$this->apireturn(0,"invalid action");
break;
}
}
private function payinfo($oid){
$orderlogic = new orderlogic();
$info = $orderlogic->getOrderInfo($oid);
Vendor('aop.AopClient');
$aop = new \AopClient();
$alipayConfig = config("alipayinfo");
$aop->gatewayUrl = $alipayConfig["gatewayUrl"];
$aop->appId = $alipayConfig["appid"];
$aop->rsaPrivateKey = $alipayConfig["privateKey"];
$aop->format = "json";
$aop->charset = "utf-8";
$aop->signType = "RSA2";
$aop->alipayrsaPublicKey = $alipayConfig["publicKey"];
Vendor("aop.request.AlipayTradeAppPayRequest");
$request = new \AlipayTradeAppPayRequest();
$request->setNotifyUrl($alipayConfig["notifyUrl"]);
$body = "你的app名稱訂單支付";
$out_trade_no = $info["number"];
$total_amount = formatMoney($info["paymoney"]["values"]);
$total_amount = 0.01;// 實(shí)際上線后注釋掉
$bizcontent = "{\"body\":\"$body\","
. "\"subject\": \"你的app名稱-訂單支付\","
. "\"out_trade_no\": \"$out_trade_no\","
. "\"timeout_express\": \"30m\","
. "\"total_amount\": \"$total_amount\","
. "\"product_code\":\"QUICK_MSECURITY_PAY\""
. "}";
$request->setBizContent($bizcontent);
$response = $aop->sdkExecute($request);
return $response;
}
public function notify()
{
$data = input("post.");
$str = ToUrlParams($data);
Vendor('aop.AopClient');
$aop = new \AopClient();
$alipayConfig = config("alipayinfo");
$aop->alipayrsaPublicKey = $alipayConfig["publicKey"];
$flag = $aop->rsaCheckV1(input("post."), NULL, "RSA2");
if($flag){
// 消息驗(yàn)證通過(guò),更改訂單狀態(tài)
$states = input("post.trade_status");
if($states == "TRADE_SUCCESS"){
$ordernumber = input("post.out_trade_no");
$paytime = input("post.gmt_payment");
$orderlogic = new orderlogic();
$orderlogic->payOrder($ordernumber,$paytime,"支付寶");
}
echo "success";
}
echo 'filed';
}
}
1.6 uni-app前端代碼
var uri = "Alipay/index.html?a=payinfo";
var param = {oid:that.orderinfo.oid}
that.$post(uri,param,"POST",function(res){
var jsondata = res.data;
// console.log(JSON.stringify(jsondata));
if(jsondata.code==1){
var orderinfo = jsondata.data;
if(orderinfo){
uni.requestPayment({
provider:"alipay",
orderInfo:orderinfo,
success:function(res){
uni.showToast({
title:"支付成功",
icon:"success",
duration:2000,
complete:function(){
uni.reLaunch({
url:"showresult?paytype=1"
});
}
});
},
fail:function(res){
uni.showToast({
title: '支付失敗,請(qǐng)到訂單中心重新支付',
icon: "none",
duration: 2000,
complete: function () {
wx.reLaunch({
url: 'showresult?paytype=3',
});
}
});
}
});
}else{
}
}else{
}
},function(){},function(){});