小程序接入微信商户支付海外版IOTPay支付

最近做了一个海外项目,需要接入海外公司提供的微信支付接口IOTPay,看了文档基本跟国内版的一致。

IOTPay 技术接入文档

微信JSAPI支付集成(微信小程序)

小程序要接入海外支付,必须主体是海外公司。中国境内公司申请的小程序无法接入海外支付。

请求URL

服务地址: https://api.iotpaycloud.com/v1/create_order

请求方式:

  • POST
  • Content-Type: application/x-www-form-urlencoded
  • 参数说明

  • 字段名变量名必填类型示例值描述
    商户IDmchIdString(30)20001222支付中心分配的商户号
    商户订单号mchOrderNoString(30)20160427210604000490商户生成的订单号,请保证唯一性
    渠道IDchannelIdString(24)WX_JSAPI小程序接口
    币种currencyString(3)CAD三位货币代码,加币:CAD
    支付金额amountint100支付金额,单位分
    客户端IPclientIpString(32)210.73.10.148客户端IP地址
    设备deviceString(64)WEB终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB
    支付结果回调URLnotifyUrlString(200)http://xxx.com/notify.php支付结果回调URL
    商品主题subjectString(64)测试商品商品主题
    商品描述信息bodyString(256)xxpay测试商品描述商品描述信息
    扩展参数1param1String(64)支付中心回调时会原样返回 
    扩展参数2param2String(64)支付中心回调时会原样返回 
    附加参数extraString(512){"openId":"o2RvowBf7sOVJf8kJksUEMceaDqo", "type":"minipay","appId":"xxxxxxxxx"} 
    子账号jobNoString(50) 商户登录名
    附言remarksString(200) 商户的附言
    签名signString(32)C380BEC2BFD727A4B6845133519F3AD6签名值,详见签名算法

    当小程序后端接收到返回值后,将返回值传回小程序前端并调用wx.requestPayment,将以下参数填入进行发起支付:

wx.requestPayment({
    appId: res.data.payParams.appId,
    timeStamp: res.data.payParams.timeStamp,
    nonceStr: res.data.payParams.nonceStr,
    package: res.data.payParams.package,
    signType: res.data.payParams.signType,
    paySign: res.data.payParams.paySign,
    success(res) {
        console.log(res);
        wx.navigateTo({
            url: '',
        })
    },
    fail(res) {
        console.log(res);
        wx.navigateTo({
            url: '',
        })
    }
})

返回结果

字段名变量名必填类型示例值描述
返回状态码retCodeString(16)SUCCESSSUCCESS/FAIL此字段是通信标识,非交易标识,交易是否成功需要查看resCode来判断
返回信息retMsgString(128)签名失败返回信息,如非空,为错误原因 签名失败 参数格式校验错误

# 以下字段在retCode和resCode都为SUCCESS的时候有返回

字段名变量名必填类型示例值描述
支付订单号payOrderIdString 支付订单号
支付参数payParamsArray 小程序调用支付需要的参数
签名signString 签名值

源码示例

Utility.php,createorder.php,notify.php

<?php

class Utility
{
    public static function request($url, $params)
    {
        $ch = curl_init();
        $this_header = array("content-type: application/x-www-form-urlencoded;charset=UTF-8");
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this_header);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }

    public static function real_ip()
    {
        static $realip = NULL;
        if ($realip !== NULL) {
            return $realip;
        }
        if (isset($_SERVER)) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                /* Take the first non-unknown valid IP string in X-Forwarded-For */
                foreach ($arr AS $ip) {
                    $ip = trim($ip);
                    if ($ip != 'unknown') {
                        $realip = $ip;
                        break;
                    }
                }
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $realip = $_SERVER['HTTP_CLIENT_IP'];
            } else {
                if (isset($_SERVER['REMOTE_ADDR'])) {
                    $realip = $_SERVER['REMOTE_ADDR'];
                } else {
                    $realip = '0.0.0.0';
                }
            }
        } else {
            if (getenv('HTTP_X_FORWARDED_FOR')) {
                $realip = getenv('HTTP_X_FORWARDED_FOR');
            } elseif (getenv('HTTP_CLIENT_IP')) {
                $realip = getenv('HTTP_CLIENT_IP');
            } else {
                $realip = getenv('REMOTE_ADDR');
            }
        }
        preg_match("/[\d\.]{7,15}/", $realip, $onlineip);
        $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0';
        return $realip;
    }

    /** Signature string
     *$prestr: Strings to be signed
     *return: Signature result
     */
    public static function md5sign($prestr, $sign_type)
    {
        $sign = '';
        if ($sign_type == 'MD5') {
            $sign = strtoupper(md5($prestr));//All uppercase letters
        } else {
            die("The signature method " . $sign_type . " is not supported at this time");
        }
        return $sign;
    }

    /**
     *Put all the elements of the array into a string with the "&" character according to the pattern of "parameter = parameter value"
     *$array: array to be stitched
     *return: string after stitching completed
     */
    public static function create_linkstring($array)
    {
        $arg = "";
        foreach ($array as $k => $v) {
            if ($v !== '') {
                $arg .= $k . '=' . $v . '&';
            }
        }
        $arg = substr($arg, 0, strlen($arg) - 1);             //Remove the last & character
        return $arg;
    }

    public static function build_mysign($sort_array, $key, $sign_type = "MD5")
    {
        $prestr = self::create_linkstring($sort_array);
        $prestr = $prestr . "&key=" . $key;
        //Connect the stitched string directly to the security check code
        $mysgin = self::md5sign($prestr, $sign_type);
        //Sign the final string to get the signature result
        return $mysgin;
    }

    /**Sort array
     *$array: array before sorting
     *return: sorted array
     */
    public static function arg_sort($array)
    {
        ksort($array, SORT_NATURAL | SORT_FLAG_CASE);
        reset($array);
        return $array;
    }
}
<?php
require_once('Utility.php');
$openid = ''; //Get openid using the interface provided by WeChat. See detail: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
$merchant_id = $_POST['merchantid'];
$merchant_key = $_POST['merchantKey'];
$url = 'https://api.iotpaycloud.com/v1/create_order';
$order_amount = $_POST['orderamount'];
$order_sn = $_SERVER['REQUEST_TIME'];
$Utility = new Utility();
$ip = $Utility->real_ip();
$notifyUrl = 'https://develop.iotpay.ca/newdemo/mini/notifyy.php?cc=00000';
$subject = 'test';
$body = 'paytest';
$sceneInfo = '{"openId":"' . $openid . '","type":"minipay","appId":"xxxxxxxxx"}';
$arr = array(
    'mchId' => $merchant_id,
    'mchOrderNo' => $order_sn,
    'channelId' => 'WX_JSAPI',
    'currency' => 'CAD',
    'amount' => intval($order_amount * 100),
    'clientIp' => $ip,
    'notifyUrl' => $notifyUrl,
    'subject' => $subject,
    'body' => $body,
    'param1' => '',
    'param2' => '',
    'extra' => $sceneInfo
);
$sort_array = $Utility->arg_sort($arr);
$arr['sign'] = $Utility->build_mysign($sort_array, $merchant_key, "MD5");//build sign
$param = 'params=' . json_encode($arr);
$outputparams = "Param: " . $param . '<br/>';
$resBody = $Utility->request($url, $param);
$res = json_decode($resBody, true);
if ($res['success'] == true) {
    return $res;
} else {
    $resarr = array(0, 'error!' . $res['retMsg'] . $res['errCodeDes']);
    return $resarr[1];
}

?>
<?php
file_put_contents("./log.txt", date("Y/m/d") . "   " . date("h:i:sa") . "   " . "Notify" . "   " . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\r\n", FILE_APPEND);
//Complete the system payment transaction process, such as: change the order payment status to paid
return "success";
?>

支付成功截图,传入了0.10CAD加币,支付的时候,根据最新汇率,转换为人民币支付。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值