uni-app IOS app微支付、支付宝整合记录

1、微支付
准备工作
1.1 在微信开放平台(https://open.weixin.qq.com)注册并认证成为开发者账号
1.2 在移动应用内创建移动应用,审核通过后获取到该应用的AppID和AppSecret
1.3 点击微支付后面的申请进入微支付申请流程,这里分为已有微商户和没有微商户两种,没有微商户的直接申请即可;已有微商户的需要进行APPID授权(产品中心→APP支付→appid授权),进行授权以后说明这个app就可以调用app支付了;
1.4 HBuilderX manifest.json文件配置APP SDK选项勾选微信支付,填入微信开放平台获取到的appid;

1.5 准备后端代码,这里我使用的是thinkphp5.0作为后端api接口关键控制器如下

    <?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,"请求成功",$ostring);
            break;
        default:
            $this->apireturn(0,"invalid action");
            break;
    }
}
private function payinfo($oid){
    $orderlogic = new orderlogic();
    $info = $orderlogic->getOrderInfo($oid);
    // 统一下单获取预支付订单信息
    $response = $this->getOrderstring("你app的名称-订单支付",$info["number"],$info["paymoney"]["values"]);
    // 生成调起支付请求的参数
    $input = new WxPayTransferPayment();
    $input->setPrepayId($response["prepay_id"]);

    if(!$input->isPrepayIdSet()){
        return ["errors"=>"缺少调起支付必填参数prepayid"];
    }
    $input->setAppid(WxPayConfig::$APPID);
    $input->setPartnerId(WxPayConfig::$MCHID);
    $input->setPackage("Sign=WXPay");
    $input->setNonceStr(self::getNonceStr());//随机字符串
    $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];

}
// 统一下单
private function getOrderstring($body,$out_trade_no,$total_amount)
{
    //统一下单
    $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;
}
/**
 * 格式化参数格式化成url参数
 */
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 签名,本函数不覆盖sign成员变量,如要设置签名需要调用setSign方法赋值
 */
private function makeSign($arr)
{
    //签名步骤一:按字典序排序参数
    ksort($arr);
    $string = $this->toUrlParams($arr);
    //签名步骤二:在string后加入KEY
    $string = $string . "&key=" . WxPayConfig::$KEY;

    //签名步骤三:MD5加密
    $string = md5($string);
    //签名步骤四:所有字符转为大写
    $result = strtoupper($string);
    return $result;
}
/**
 *
 * 产生随机字符串,不长于32位
 * @param int $length
 * @return string 产生的随机字符串
 */
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代码如下,点击支付后执行如下代码

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: '支付失败,请到订单中心重新支付',
                                        icon: "none",
                                        duration: 2000,
                                        complete: function () {
                                            wx.reLaunch({
                                                url: 'showresult?paytype=3',
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    }else{
                        
                    }
                },function(){},function(){});

注意 注意 注意:如果是默认基座的话会提示:HBuilder mainifest.json中配置的支付appid和生成订单使用的appid不一致,如果是HB调试请在线打包,http://ask.dcloud.net.cn/article/282",必须使用自定义基座才能真机调试支付

2、支付宝支付
准备工作
1.1 在支付宝平台注册商户用户
1.2 在支付宝商户后台产品中心签约app支付
1.3 在蚂蚁金服开放平台(https://open.alipay.com)开发中心→网页和移动应用 新增app应用,通过以后设置好应用公钥,系统会自动生成支付宝公钥 注意新增的时候 iOS bundle ID一定要填写正确
1.4 HBuilder mainifest.json中设置支付宝ios scheme用于支付完成跳转回应用。
1.5 后台代码参考支付宝示例代码

<?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,"请求成功",$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;// 实际上线后注释掉
    $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){
        // 消息验证通过,更改订单状态
        $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: '支付失败,请到订单中心重新支付',
                                        icon: "none",
                                        duration: 2000,
                                        complete: function () {
                                            wx.reLaunch({
                                                url: 'showresult?paytype=3',
                                            });
                                        }
                                    });
                                }
                            });
                        }else{
                            
                        }
                    }else{
                        
                    }
                },function(){},function(){});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343