一直不太喜欢用官方的sdk。因为如果有更新,还要重新下载sdk,还要修改一些东西。感觉挺不方便的。所以我一般都是调用api生撸。但是支付宝的文档真的很生涩,调试半天终于弄好了。记录一下吧。
直接上代码:
$time = time();try{$order = self::$db->table('scanpay_order')->add(array('amount' => $amount, 'marketid' => $marketid, 'deskid' => $cashier_desk, 'cashier_uid' => $cashier_uid, 'dateline' => $time, 'pay_type' => 2));//上面这一行,是往数据库写一条记录。根据你的业务逻辑,这一步也可以省略。对你来说语法可能并不完全熟悉,因为我用的是我自己写的一个php框架。}catch(\Exception $e){return array('code' => -101, 'message' => $e->getMessage());}vendor('WXSdk/WXSdk');$wxsdk = new \WXSdk("", "");//上面这2行,是为了后面调用curl准备的。你也可以不用管它。它也是我自己写的一个小工具。$appid = '2021004104687588';$method = 'alipay.trade.pay';$charset = 'utf-8';$sign_type = 'RSA2';$timestamp = date('Y-m-d H:i:s', $time);$version = '1.0';$out_trade_no = 'scanpay_ali_' . $order; //上面这行是商户自已的订单号,这个你自己定。方便使用就好。$total_amount = $amount;//这个是订单金额。单位是元$subject = 'WormJan的商品'; //商品标题$auth_code = $code; //这个就是扫描到的用户的支付条码了$scene = 'bar_code'; //固定$arr = array('out_trade_no' => $out_trade_no, 'total_amount' => $total_amount, 'subject' => $subject, 'auth_code' => $auth_code, 'scene' => $scene);$biz_content = json_encode($arr);$arr_final = array('app_id' => $appid, 'method' => $method, 'charset' => $charset, 'sign_type' => $sign_type, 'timestamp' => $timestamp, 'version' => $version, 'biz_content' => $biz_content);$str = $wxsdk->order_str($arr_final); //上面这个是按键值排序,然后生成 a=b&c=d 这样的字符串。后面我把这个方法贴出来吧。这个是我小工具里的一个方法。可以自己写$str = urldecode($str);$signature = '';$priv_key = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/cert_alipay/app_private_key.txt'); //应用私钥。这个要注意了。从支付宝工具中生成的私钥,是纯base64的,你要在内容前面加上一行 -----BEGIN RSA PRIVATE KEY-----,在后面另起一行加上 -----END RSA PRIVATE KEY----- ,私钥内容要在一行里面。那么也就是说,密钥文件里一共三行内容。$priv_key = wordwrap($priv_key, 64, "\n", true); //从网上找的,说必须这么整一下。我就听了。$key = openssl_pkey_get_private($priv_key);if($key === false){debug("openssl_get_privatekey失败" . openssl_error_string()); //debug我自己写的一个函数。这个随便你了,可以不用。}openssl_sign($str, $signature, $key, 'SHA256');openssl_free_key($key);$sign = base64_encode($signature); //这个就是最终的sign了。$post_final = $str . "&sign=" . urlencode($sign); //传递的时候,要encode一下$url = 'https://openapi.alipay.com/gateway.do';$result = $wxsdk->curl_post_ssl($url, $post_final); //curl向支付宝网关提交数据。这个是我小工具里的方法。大家可以自行写一下。后面我传上来也行$result = (array)json_decode($result, true); //上面这一行将返回结果由json转为数组,方便取值$result['out_trade_no'] = $out_trade_no; //根据业务逻辑,上面这一行不要也可以return($result);
下面是我的curl函数
public function curl_post_ssl($url, $vars, $cert = '', $key = ''){$ch = curl_init();curl_setopt($ch,CURLOPT_TIMEOUT, 30);curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch,CURLOPT_URL, $url);curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false);//以下两种方式需选择一种if($cert != ''){curl_setopt($ch, CURLOPT_SSLCERT, $cert);}if($key != ''){curl_setopt($ch, CURLOPT_SSLKEY, $key);}curl_setopt($ch,CURLOPT_POST, true);curl_setopt($ch,CURLOPT_POSTFIELDS, $vars);$data = curl_exec($ch);if($data){curl_close($ch);return $data;} else {$error = curl_errno($ch);echo "call faild, errorCode:$error\n";curl_close($ch);return false;}}
//vars 就是要传递的参数。这里是字符串。 cert 和key用不到。因为我们用的是密钥方式。
下面是我的字符串排序的函数
function order_str($param){if(!$param){return false;}//按键排序ksort($param);//拿到待签名字符串$str = http_build_query($param);return $str;}
//param 参数是一个数组。就是你要排序的那些内容。
/*例如:
array("b" => 2, "a" => 1)
会给你弄成 a=1&b=2
*/