epay / website /plugins /sandpay /sandpay_plugin.php
xxsxx's picture
Upload 1045 files
0d5b03e verified
<?php
class sandpay_plugin
{
static public $info = [
'name' => 'sandpay', //支付插件英文名称,需和目录名称一致,不能有重复
'showname' => '杉德支付', //支付插件显示名称
'author' => '杉德', //支付插件作者
'link' => 'https://www.sandpay.com.cn/', //支付插件作者链接
'types' => ['alipay','wxpay','bank'], //支付插件支持的支付方式,可选的有alipay,qqpay,wxpay,bank
'transtypes' => ['bank'], //支付插件支持的转账方式,可选的有alipay,qqpay,wxpay,bank
'inputs' => [ //支付插件要求传入的参数以及参数显示名称,可选的有appid,appkey,appsecret,appurl,appmchid
'appid' => [
'name' => '商户编号',
'type' => 'input',
'note' => '',
],
'appkey' => [
'name' => '私钥证书密码',
'type' => 'input',
'note' => '',
],
'appswitch' => [
'name' => '环境选择',
'type' => 'select',
'options' => [0=>'生产环境',1=>'测试环境'],
],
],
'select_bank' => [
'1' => '银联支付',
'2' => '快捷支付',
],
'select' => null,
'note' => '将私钥证书命名为client.pfx(或商户编号.pfx)上传到 /plugins/sandpay/cert/', //支付密钥填写说明
'bindwxmp' => true, //是否支持绑定微信公众号
'bindwxa' => true, //是否支持绑定微信小程序
];
static public function submit(){
global $siteurl, $channel, $order, $sitename;
if($order['typename']=='alipay'){
return ['type'=>'jump','url'=>'/pay/alipay/'.TRADE_NO.'/'];
}elseif($order['typename']=='wxpay'){
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger')!==false && $channel['appwxmp']>0){
return ['type'=>'jump','url'=>'/pay/wxjspay/'.TRADE_NO.'/?d=1'];
}elseif(checkmobile()==true && $channel['appwxa']>0){
return ['type'=>'jump','url'=>'/pay/wxwappay/'.TRADE_NO.'/'];
}else{
return ['type'=>'jump','url'=>'/pay/wxpay/'.TRADE_NO.'/'];
}
}elseif($order['typename']=='bank'){
if(in_array('2',$channel['apptype'])){
return ['type'=>'jump','url'=>'/pay/fastpay/'.TRADE_NO.'/'];
}else{
return ['type'=>'jump','url'=>'/pay/bank/'.TRADE_NO.'/'];
}
}
}
static public function mapi(){
global $siteurl, $channel, $order, $conf, $device, $mdevice;
if($order['typename']=='alipay'){
return self::alipay();
}elseif($order['typename']=='wxpay'){
if($mdevice=='wechat' && $channel['appwxmp']>0){
return ['type'=>'jump','url'=>$siteurl.'/pay/wxjspay/'.TRADE_NO.'/?d=1'];
}elseif($device=='mobile' && $channel['appwxa']>0){
return ['type'=>'jump','url'=>$siteurl.'/pay/wxwappay/'.TRADE_NO.'/'];
}else{
return self::wxpay();
}
}elseif($order['typename']=='bank'){
if(in_array('2',$channel['apptype'])){
return self::fastpay();
}else{
return self::bank();
}
}
}
//扫码下单
static private function qrcode($productId, $payTool){
global $channel, $order, $ordername, $conf, $clientip;
require(PAY_ROOT."inc/Build.class.php");
$client = new SandpayCommon($channel['appid'], $channel['appkey'], $channel['appswitch']);
$client->productId = $productId;
$client->body = array(
'payTool' => $payTool,
'orderCode' => TRADE_NO,
'totalAmount' => str_pad(strval($order['realmoney']*100),12,'0',STR_PAD_LEFT),
'subject' => $ordername,
'body' => $ordername,
'notifyUrl' => $conf['localurl'].'pay/notify/'.TRADE_NO.'/',
);
return \lib\Payment::lockPayData(TRADE_NO, function() use($client) {
$ret = $client->request('orderCreate');
return $ret['qrCode'];
});
}
//收银台下单
static private function cashier(){
global $siteurl, $channel, $order, $ordername, $conf, $clientip;
require(PAY_ROOT."inc/Build.class.php");
$client = new SandpayCommon($channel['appid'], $channel['appkey'], $channel['appswitch']);
$client->productId = '00002000';
$client->body = array(
'orderCode' => TRADE_NO,
'totalAmount' => str_pad(strval($order['realmoney']*100),12,'0',STR_PAD_LEFT),
'subject' => $ordername,
'body' => $ordername,
'notifyUrl' => $conf['localurl'].'pay/notify/'.TRADE_NO.'/',
'frontUrl' => $siteurl.'pay/return/'.TRADE_NO.'/',
);
$html_text = $client->form('cashierPay');
return ['type'=>'html','data'=>$html_text];
}
//新版H5跳转下单
static private function newh5($product_code, $pay_extra = []){
global $siteurl, $channel, $order, $ordername, $conf, $clientip;
require(PAY_ROOT."inc/Build.class.php");
$client = new SandpayCommon($channel['appid'], $channel['appkey'], $channel['appswitch']);
$param = [
'version' => '10',
'mer_no' => $channel['appid'],
'mer_order_no' => TRADE_NO,
'create_time' => date('YmdHis'),
'order_amt' => $order['realmoney'],
'notify_url' => $conf['localurl'].'pay/notify/'.TRADE_NO.'/',
'return_url' => $siteurl.'pay/return/'.TRADE_NO.'/',
'create_ip' => str_replace('.','_',$clientip),
'pay_extra' => json_encode($pay_extra),
'accsplit_flag' => 'NO',
'sign_type' => 'RSA',
'store_id' => '000000',
];
$param['sign'] = $client->getSign($param);
$param += [
'expire_time' => date('YmdHis', time()+30*60),
'goods_name' => $ordername,
'product_code' => $product_code,
'clear_cycle' => '1',
'jump_scheme' => 'sandcash://scpay',
'meta_option' => json_encode([["s" => "Android","n" => "wxDemo","id" => "com.pay.paytypetest","sc" => "com.pay.paytypetest"]]),
];
$query = http_build_query($param);
if($product_code == '02010006'){
$attr = 'applet';
}elseif($product_code == '02020005'){
$attr = 'alipaycode';
}elseif($product_code == '02010002'){
$attr = 'wechatpay';
}elseif($product_code == '02020002'){
$attr = 'alipay';
}elseif($product_code == '02000001'){
$attr = 'qrcode';
}elseif($product_code == '05030001'){
$attr = 'fastpayment';
}elseif($product_code == '06030001'){
$attr = 'unionpayh5';
}
if($channel['appswitch'] == 1){
$payurl = "https://sandcash-uat01.sand.com.cn/pay/h5/".$attr."?".$query;
}else{
$payurl = "https://sandcash.mixienet.com.cn/pay/h5/".$attr."?".$query;
}
return $payurl;
}
//支付宝扫码支付
static public function alipay(){
/*if (checkmobile()==true) {
$payurl = self::newh5('02020002');
return ['type'=>'jump','url'=>$payurl];
}else{*/
try{
$code_url = self::qrcode('00000006','0401');
}catch(Exception $ex){
return ['type'=>'error','msg'=>'支付宝支付下单失败!'.$ex->getMessage()];
}
return ['type'=>'qrcode','page'=>'alipay_qrcode','url'=>$code_url];
//}
}
//微信扫码支付
static public function wxpay(){
try{
$code_url = self::qrcode('00000005','0402');
}catch(Exception $ex){
return ['type'=>'error','msg'=>'微信支付下单失败!'.$ex->getMessage()];
}
if (checkmobile()==true) {
return ['type'=>'qrcode','page'=>'wxpay_wap','url'=>$code_url];
}else{
return ['type'=>'qrcode','page'=>'wxpay_qrcode','url'=>$code_url];
}
}
//云闪付扫码支付
static public function bank(){
try{
$code_url = self::qrcode('00000012','0403');
}catch(Exception $ex){
return ['type'=>'error','msg'=>'云闪付下单失败!'.$ex->getMessage()];
}
return ['type'=>'qrcode','page'=>'bank_qrcode','url'=>$code_url];
}
//快捷支付
static public function fastpay(){
if(checkmobile())
$payurl = self::newh5('06030001');
else
$payurl = self::newh5('05030001');
return ['type'=>'jump','url'=>$payurl];
}
//微信公众号
static public function wxjspay(){
global $siteurl, $channel, $order, $ordername, $conf, $clientip;
$wxinfo = \lib\Channel::getWeixin($channel['appwxmp']);
if(!$wxinfo) return ['type'=>'error','msg'=>'支付通道绑定的微信公众号不存在'];
try{
$tools = new \WeChatPay\JsApiTool($wxinfo['appid'], $wxinfo['appsecret']);
$openid = $tools->GetOpenid();
}catch(Exception $e){
return ['type'=>'error','msg'=>$e->getMessage()];
}
$blocks = checkBlockUser($openid, TRADE_NO);
if($blocks) return $blocks;
$payurl = self::newh5('02010002', ["mer_app_id"=>$wxinfo['appid'],"openid"=>$openid]);
return ['type'=>'jump','url'=>$payurl];
}
//微信H5包装云函数
static public function wxwappay(){
global $siteurl, $channel, $order, $ordername, $conf, $clientip;
$wxinfo = \lib\Channel::getWeixin($channel['appwxa']);
if(!$wxinfo) return ['type'=>'error','msg'=>'支付通道绑定的微信小程序不存在'];
$payurl = self::newh5('02010006', ["resourceAppid"=>$wxinfo['appid'],"resourceEnv"=>""]);
return ['type'=>'jump','url'=>$payurl];
}
//异步回调
static public function notify(){
global $channel, $order;
$sign = $_POST['sign']; //签名
$data = stripslashes($_POST['data']); //支付数据
//file_put_contents('logs.txt', 'sign='.$_POST['sign']."\r\n\r\ndata=".$_POST['data']);
require(PAY_ROOT."inc/Build.class.php");
$client = new SandpayCommon($channel['appid'], $channel['appkey'], $channel['appswitch']);
$verifyFlag = $client->verify($data, $sign);
if($verifyFlag){
$array = json_decode($data, true);
if($array['head']['respCode'] == '000000'){
$out_trade_no = $array['body']['orderCode'];
$trade_no = $array['body']['tradeNo'];
$money = $array['body']['totalAmount'];
$buyer = $array['body']['accLogonNo'];
if($out_trade_no == TRADE_NO){
processNotify($order, $trade_no, $buyer);
}
return ['type'=>'html','data'=>'respCode=000000'];
}
}
return ['type'=>'html','data'=>'respCode=020002'];
}
//支付返回页面
static public function return(){
return ['type'=>'page','page'=>'return'];
}
//退款
static public function refund($order){
global $channel, $conf;
if(empty($order))exit();
require(PAY_ROOT."inc/Build.class.php");
$client = new SandpayCommon($channel['appid'], $channel['appkey'], $channel['appswitch']);
$client->body = array(
'orderCode' => $order['api_trade_no'], //新的订单号
'oriOrderCode' => $order['trade_no'], //原订单号
'refundAmount' => str_pad(strval($order['refundmoney']*100),12,'0',STR_PAD_LEFT), //退款金额
'notifyUrl' => $conf['localurl'].'pay/refundnotify/'.TRADE_NO.'/',
);
try{
$ret = $client->request('orderRefund');
return ['code'=>0, 'trade_no'=>$ret['orderCode'], 'refund_fee'=>$ret['refundAmount']];
}catch(Exception $ex){
return ['code'=>-1,'msg'=>$ex->getMessage()];
}
}
//退款回调
static public function refundnotify(){
global $channel, $order;
$sign = $_POST['sign']; //签名
$data = stripslashes($_POST['data']); //支付数据
require(PAY_ROOT."inc/Build.class.php");
$client = new SandpayCommon($channel['appid'], $channel['appkey'], $channel['appswitch']);
$verifyFlag = $client->verify($data, $sign);
if($verifyFlag){
$array = json_decode($data, true);
if($array['head']['respCode'] == '000000'){
$out_trade_no = $array['body']['orderCode'];
$trade_no = $array['body']['tradeNo'];
$money = $array['body']['totalAmount'];
return ['type'=>'html','data'=>'respCode=000000'];
}
}
return ['type'=>'html','data'=>'respCode=020002'];
}
//转账
static public function transfer($channel, $bizParam){
if(empty($channel) || empty($bizParam))exit();
require(PAY_ROOT."inc/Transfer.class.php");
$client = new SandpayTransfer($channel['appid'], $channel['appkey']);
try{
$result = $client->agentpay($bizParam['out_biz_no'], $bizParam['payee_account'], $bizParam['payee_real_name'], $bizParam['money'], $bizParam['transfer_desc']);
if (isset($result['respCode']) && $result['respCode']=='0000') {
$status = $result['resultFlag'] == 0 ? 1 : 0;
return ['code'=>0, 'status'=>$status, 'orderid'=>$result['sandSerial'], 'paydate'=>$result['tranDate']];
}else{
return ['code'=>-1, 'errcode'=>$result['respCode'], 'msg'=>'['.$result['respCode'].']'.$result['respDesc']];
}
}catch(Exception $ex){
return ['code'=>-1, 'msg'=>$ex->getMessage()];
}
}
//转账查询
static public function transfer_query($channel, $bizParam){
if(empty($channel) || empty($bizParam))exit();
require(PAY_ROOT."inc/Transfer.class.php");
$client = new SandpayTransfer($channel['appid'], $channel['appkey']);
try{
$result = $client->queryOrder($bizParam['out_biz_no']);
if (isset($result['respCode']) && $result['respCode']=='0000') {
$status = $result['resultFlag'] == 0 ? 1 : 0;
return ['code'=>0, 'status'=>$status];
}else{
return ['code'=>-1, 'msg'=>'['.$result['respCode'].']'.$result['respDesc']];
}
}catch(Exception $ex){
return ['code'=>-1, 'msg'=>$ex->getMessage()];
}
}
//余额查询
static public function balance_query($channel, $bizParam){
if(empty($channel))exit();
require(PAY_ROOT."inc/Transfer.class.php");
$client = new SandpayTransfer($channel['appid'], $channel['appkey']);
$out_biz_no = date("YmdHis").rand(11111,99999);
try{
$result = $client->queryBalance($out_biz_no);
if (isset($result['respCode']) && $result['respCode']=='0000') {
return ['code'=>0, 'ammount'=>$result['balance'], 'msg'=>'当前账户余额:'.$result['balance'].' 元,可用额度:'.$result['creditAmt']];
}else{
return ['code'=>-1, 'msg'=>'['.$result['respCode'].']'.$result['respDesc']];
}
}catch(Exception $ex){
return ['code'=>-1, 'msg'=>$ex->getMessage()];
}
}
}