快钱聚合支付(一码付)对接demo

备注:以下代码基于PHP laravel框架,引用了自带的函数。array_get($array, "key") 为数组中取元素,类似于$array["key"]。快钱后端语言为java,对接快钱时遇到了一些问题,今天整理下,希望可以帮到更多的人。

一、后端拼接唤起支付url

/**
  * 快钱一码付(聚合支付)相关配置
  */
$kuaiqian = [
        "merchantCode" => "10210xxxxxx",                                                    //商户会员号
        "merchantId"   => "812310xxxxx",                                                    //商户编号
        "terminalId"   => "71075xxxxx",                                                     //终端编号
        "key"          => "xxxxxxx",                                                        //支付秘钥
        "payUrl"       => "https://pay.99bill.com/prod/html/agent-static/index.html",       //快钱前端唤起支付url
        "returnUrl"    => "https://xxx/return_url",                                         //支付成功,前端回调url
]

/**
 * 拼接支付参数
 * @param $orderNumber
 */
function getPayUrl($orderNumber, $money)
{
    $data = [
        "requestTime"       => date("YmdHis"),
        "externalTraceNo"   => $orderNumber,
        "merchantCode"      => array_get($kuaiqian, "merchantCode"),
        "merchantId"        => array_get($kuaiqian, "merchantId"),
        "terminalId"        => array_get($kuaiqian, "terminalId"),
        "amt"               => $money,
        "returnUrl"         => array_get($kuaiqian, "returnUrl")."?orderNumber=".$orderNumber      //前端同步回调地址
    ];
    $sign = kuaiqian_sign($data);
    $data["secretInfo"] = $sign;
    $string = "";
    foreach ($data as $key => $value) {
        $string .= $key."=".$value."&";
    }
    return array_get($kuaiqian, "payUrl")."?".rtrim($string, "&");
}

/**
 * 快钱支付签名
 */
function kuaiqian_sign($data)
{
    ksort($data);
    $res = "";
    foreach ($data as $key => $value) {
        if (!$value) continue;                      //参数值为空时不参与签名
        $res .= $key."=".$value."&";
    }
    $stringSignTemp = $res."key=".array_get($kuaiqian, "key");
    return strtoupper(md5($stringSignTemp));
}

二、回调签名(和支付、微信不同的是快钱的回调地址需要提前和业务联系配置)

/**
 * 支付异步回调
 * @param Request $request
 */
function payNotify(PayRepository $payRepository)
{
    $request = file_get_contents("php://input");
    $request = explode("&", $request);
    //将回调数组转为完整数组
    foreach ($request as $data) {
        $tmp = explode("=", $data);
        $result[array_get($tmp, "0")] = urldecode(array_get($tmp, "1"));
    }
    //支付回调签名验证
    $signVerify = kuaiqian_notify_sign_verify($result);
    //签名不通过
    if (!$signVerify) {
        return "1";
    }
    //系统内部订单号
    $orderNumber = array_get($result, "externalTraceNo");
    //订单已经支付成功,不需要重复回调
    if (array_get($payOrder, "status") != PayOrder::PAY_ORDER_STATUS_NOT) {
        return "0";
    }
    if (array_get($result, "processFlag") === "0") {   //支付成功,处理内部业务逻辑
        $result = "success";   //处理支付成功以后的业务逻辑
        if (!$result) {
            return "1";
        } else {
            return "0";
        }
    } else {                                           //支付不成功,也不允许再次回调
        return "0";
    }
}

/**
 * 快钱支付接口通知验签结果校验
 * @param  $datas  array  快钱回调完整报文
 */
function kuaiqian_notify_sign_verify($datas)
{
    $signature = array_get($datas, "signature");    //获取签名
    //获取参与验签的数组节点(array_only()为laravel封装的函数,获取数组中指定键的参数,可以自己封装。)
    $datas = array_only($datas, ["processFlag", "txnType", "orgTxnType", "amt", "externalTraceNo", "orgExternalTraceNo",
        "terminalOperId", "authCode", "RRN", "txnTime", "shortPAN", "responseCode", "cardType", "issuerId"]);
    //节点值为空时屏蔽节点,不需要参与验签
    foreach ($datas as $key => $value) {
        if ($datas[$key] === "") {
            unset($datas[$key]);
        }
    }
    $result = implode("", $datas);        //等待验签字符串拼接
    $publicKey = openssl_get_publickey(file_get_contents(public_path("xxxx/public.pem")));    #特别强调:验签公钥快钱给的是.cer格式,PHP需要转为pem(openssl x509 -inform der -in xx.cer  xx.pem)
    return openssl_verify($result, base64_decode($signature), $publicKey);
}

三、后记
快钱后端为Java,导致回调验签的时候费了好大力气才搞定,今天整理了下,需要的伙伴可以试试,有问题可以私我。(快钱做大做强了,但技术对接服务这块真的不怎么样,坑死。)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,176评论 5 469
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,190评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,232评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,953评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,879评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,177评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,626评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,295评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,436评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,365评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,414评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,096评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,685评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,771评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,987评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,438评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,032评论 2 341