官方sdk Demo
支付宝 请求支付代码
public function alipay(){
$arr =input('param.');
vendor('alipay-trade-page-pay/aop/AopClient');
vendor('alipay-trade-page-pay/aop/request/AlipayTradePagePayRequest');
$amount = $arr['amount'];
$store_user_id = $arr['store_user_id'];
$renew_price_id = $arr['renew_price_id'];
$renew_service_id = $arr['renew_service_id'];
$rand = date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
Renew::insert(['store_user_id'=>$store_user_id,'pay_status'=>0,'create_time'=>time(),'renew_price_id'=>$renew_price_id,'renew_service_id'=>$renew_service_id,'out_trade_no'=>$rand]);
/** 初始化 **/
$aop = new \AopClient ();
/** 支付宝网关 **/
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
/** 应用id,如何获取请参考:https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
$aop->appId = '';
/** 密钥格式为pkcs1,如何获取私钥请参考:https://opensupport.alipay.com/support/helpcenter/207/201602469554 **/
$aop->rsaPrivateKey = '';
/** 支付宝公钥,如何获取请参考:https://opensupport.alipay.com/support/helpcenter/207/201602487431 **/
$aop->alipayrsaPublicKey='';
/** 签名算法类型 **/
$aop->signType = 'RSA2';
/** 请求使用的编码格式 **/
$aop->postCharset='utf-8';
/** 仅支持JSON **/
$aop->format='json';
/** 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.page.pay(电脑网站支付) **/
$request = new \AlipayTradePagePayRequest ();
/** 设置业务参数 **/
$request->setBizContent("{" .
/** 商户订单号,商户自定义,需保证在商户端不重复,如:20200612000001 **/
"\"out_trade_no\":\".$rand.\"," .
/** 销售产品码,固定值:FAST_INSTANT_TRADE_PAY **/
"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," .
/** 订单金额,精确到小数点后两位 **/
"\"total_amount\":\"$amount\"," .
/** 订单标题 **/
"\"subject\":\"宠物商户商城续费\"," .
/** 业务扩展参数 **/
//"\"extend_params\":{" .
/** 花呗分期参数传值前提:必须有该接口花呗收款准入条件,且需签约花呗分期 **/
/** 指定可选期数,只支持3/6/12期,还款期数越长手续费越高 **/
// "\"hb_fq_num\":\"3\"," .
/** 指定花呗分期手续费承担方式,手续费可以由用户全承担(该值为0),也可以商户全承担(该值为100),但不可以共同承担,即不可取0和100外的其他值。 **/
//"\"hb_fq_seller_percent\":\"100\"" .
// "}," .
/** 订单描述 **/
"\"body\":\"商户商城续费\"" .
"}");
/** 注:支付结果以异步通知为准,不能以同步返回为准,因为如果实际支付成功,但因为外力因素,如断网、断电等导致页面没有跳转,则无法接收到同步通知;**/
/** 支付完成的跳转地址,用于用户视觉感知支付已成功,传值外网可以访问的地址,如果同步未跳转可参考该文档进行确认:https://opensupport.alipay.com/support/helpcenter/193/201602474937 **/
$request->setReturnUrl("https://www.baidu.com");
/** 异步通知地址,以http或者https开头的,商户外网可以post访问的异步地址,用于接收支付宝返回的支付结果,如果未收到该通知可参考该文档进行确认:https://opensupport.alipay.com/support/helpcenter/193/201602475759 **/
$request->setNotifyUrl("https://www.baidu.com");
/** 调用SDK生成form表单 **/
$result = $aop->pageExecute ($request);
/** 调用SDK生成支付链接,可在浏览器打开链接进入支付页面 **/
//$result = $aop->pageExecute ($request,'get');
/** 第三方调用(服务商模式),传值app_auth_token后,会收款至授权token对应商家账号,如何获传值app_auth_token请参考文档:https://opensupport.alipay.com/support/helpcenter/79/201602494631 **/
//$result = $aop->pageExecute($request,'get',"传入获取到的app_auth_token值");
/** 获取接口调用结果,如果调用失败,可根据返回错误信息到该文档寻找排查方案:https://opensupport.alipay.com/support/helpcenter/97 **/
print_r($result);
}
支付宝异步通知代码
public function alipayNotify(){
vendor('alipay-trade-page-pay/config');
vendor('alipay-trade-page-pay/pagepay/service/AlipayTradeService');
$config = array (
//应用ID,您的APPID。
'app_id' => "",
//商户私钥
'merchant_private_key' => "",
//异步通知地址
'notify_url' => "http://www.baidu.com",
//同步跳转
'return_url' => "http://www.baidu.com",
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "",
);
$arr =input('param.');
$alipaySevice = new \AlipayTradeService($config);
$alipaySevice->writeLog(var_export($arr,true));
$result = $alipaySevice->check($arr);
/* 实际验证过程建议商户添加以下校验。
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
if($result) {//验证成功
/
//请在这里加上商户的业务逻辑程序代
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
//获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
//商户订单号
$out_trade_no = $arr['out_trade_no'];
//支付宝交易号
$trade_no = $arr['trade_no'];
//交易状态
$trade_status = $arr['trade_status'];
if($arr['trade_status'] == 'TRADE_FINISHED') {
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
}
else if ($arr['trade_status'] == 'TRADE_SUCCESS') {
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
//如果有做过处理,不执行商户的业务程序
//注意:
//付款完成后,支付宝系统发送该交易状态通知
//修改该笔为已支付成功
$order_info = Renew::where(['out_trade_no'=>$out_trade_no])->find();
if(count($order_info) > 0){
Renew::where(['out_trade_no'=>$out_trade_no])->update(['pay_status'=>1,'pay_time'=>time()]);
}
}
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
echo "success"; //请不要修改或删除
}else {
//验证失败
echo "fail";
}
}
微信支付代码 扫码支付 模式二 需注意:微信官方sdk引入tp有点问题 使用绝对路径并且vendor函数引入必须不能有"." vendor(‘wx_php_sdk_pay/example/WxPayNativePay’);引入示例:require_once realpath(dirname(FILE).’/…/lib/WxPay.Config.Interface.php’);
public function wxNativePay(){
vendor('wx_php_sdk_pay/example/WxPayNativePay');
vendor('wx_php_sdk_pay/example/phpqrcode/phpqrcode');
//('wx-php-sdk-pay/lib/WxPay.Api.php');
//import('wx-php-sdk-pay/WxPay.NativePay.php');
$arr =input('param.');
$amount = $arr['amount'];
$store_user_id = $arr['store_user_id'];
$renew_price_id = $arr['renew_price_id'];
$renew_service_id = $arr['renew_service_id'];
$rand = date('YmdHis').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
Renew::insert(['store_user_id'=>$store_user_id,'pay_status'=>0,'create_time'=>time(),'renew_price_id'=>$renew_price_id,'renew_service_id'=>$renew_service_id,'out_trade_no'=>$rand]);
//初始化日志
// $logHandler= new \CLogFileHandler("../logs/".date('Y-m-d').'.log');
// $log = Log::Init($logHandler, 15);
//模式一
//不再提供模式一支付方式
/**
* 流程:
* 1、组装包含支付信息的url,生成二维码
* 2、用户扫描二维码,进行支付
* 3、确定支付之后,微信服务器会回调预先配置的回调地址,在【微信开放平台-微信支付-支付配置】中进行配置
* 4、在接到回调通知之后,用户进行统一下单支付,并返回支付信息以完成支付(见:native_notify.php)
* 5、支付完成之后,微信服务器会通知支付成功
* 6、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
*/
$notify = new \NativePay ();
// $url1 = $notify->GetPrePayUrl("123456789");
//模式二
/**
* 流程:
* 1、调用统一下单,取得code_url,生成二维码
* 2、用户扫描二维码,进行支付
* 3、支付完成之后,微信服务器会通知支付成功
* 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
*/
$input = new \WxPayUnifiedOrder ();
$input->SetBody("宠物商户后台续费");
$input->SetAttach("宠物商户后台续费");
$input->SetOut_trade_no($rand);
$input->SetTotal_fee($amount*100);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetGoods_tag("宠物商户后台续费");
$input->SetNotify_url("https://www.baidu.com/wx_notify.php");
$input->SetTrade_type("NATIVE");
$input->SetProduct_id("123456789");
$result = $notify->GetPayUrl($input);
$url2 = $result["code_url"];
if(substr($url2, 0, 6) == "weixin"){
ob_start();
$file = \QRcode::png($url2);
$file = ob_get_contents();
ob_clean();
$base64_data = base64_encode($file);
$base64_file = 'data:image/png;base64,'.$base64_data;
return $base64_file;
}else{
header('HTTP/1.1 404 Not Found');
}
}
微信异步通知
public function wxNotify(){
//获取接口数据,如果$_REQUEST拿不到数据,则使用file_get_contents函数获取
$post =input('param.');
if ($post == null) {
$post = file_get_contents("php://input");
}
if ($post == null) {
$post = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
}
if (empty($post) || $post == null || $post == '') {
//阻止微信接口反复回调接口 文档地址 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7,下面这句非常重要!!!
$str=' ';
echo $str;
exit('Notify 非法回调');
}
/*****************微信回调返回数据样例*******************
$post = '
';
*************************微信回调返回*****************/
libxml_disable_entity_loader(true); //禁止引用外部xml实体
$xml = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);//XML转数组
// $post_data = (array)$xml;
$post_data = json_decode(json_encode($xml),true);
/** 解析出来的数组
*Array
* (
* [appid] => wx1c870c0145984d30
* [bank_type] => CFT
* [cash_fee] => 100
* [fee_type] => CNY
* [is_subscribe] => N
* [mch_id] => 1297210301
* [nonce_str] => gkq1x5fxejqo5lz5eua50gg4c4la18vy
* [openid] => olSGW5BBvfep9UhlU40VFIQlcvZ0
* [out_trade_no] => fangchan_588796
* [result_code] => SUCCESS
* [return_code] => SUCCESS
* [sign] => F6890323B0A6A3765510D152D9420EAC
* [time_end] => 20180626170839
* [total_fee] => 100
* [trade_type] => JSAPI
* [transaction_id] => 4200000134201806265483331660
* )
**/
//订单号
$out_trade_no = isset($post_data['out_trade_no']) && !empty($post_data['out_trade_no']) ? $post_data['out_trade_no'] : 0;
//查询订单信息
$order_info = Renew::where(['out_trade_no'=>$out_trade_no])->find();
// file_put_contents(dirname(__FILE__).DIRECTORY_SEPARATOR."../../log.txt", date ( "Y-m-d H:i:s" ) . " " . json_encode($post_data)."\r\n", FILE_APPEND );
if(count($order_info) > 0){
//平台支付key
$wxpay_key = '';
//接收到的签名
$post_sign = $post_data['sign'];
unset($post_data['sign']);
//重新生成签名
$newSign = $this->MakeSign($post_data,$wxpay_key);
// file_put_contents(dirname(__FILE__).DIRECTORY_SEPARATOR."../../log.txt", date ( "Y-m-d H:i:s" ) . " " . $newSign."\r\n".$post_sign. "\r\n", FILE_APPEND );
//签名统一,则更新数据库
if($post_sign == $newSign){
//更新数据库
if($post_data['return_code'] == 'SUCCESS' && $post_data['result_code'] == 'SUCCESS'){
//执行业务逻辑
Renew::where(['out_trade_no'=>$out_trade_no])->update(['pay_status'=>1,'pay_time'=>time()]);
}
}
}
//阻止微信接口反复回调接口 文档地址 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=7,下面这句非常重要!!!
$str=' ';
echo $str;
}
public function MakeSign($params, $key)
{
//签名步骤一:按字典序排序参数
ksort($params);
$string = $this->ToUrlParams($params);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$key;
//签名步骤三:MD5加密或者HMAC-SHA256
$string = hash_hmac("sha256",$string ,$key);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
public function ToUrlParams( $params ){
$string = '';
if( !empty($params) ){
$array = array();
foreach( $params as $key => $value ){
$array[] = $key.'='.$value;
}
$string = implode("&",$array);
}
return $string;
}