├── src ├── Weixin │ ├── Reply │ │ ├── Pay.php │ │ ├── Base.php │ │ └── PayMode1.php │ ├── Report │ │ ├── Trades.php │ │ └── Request.php │ ├── Shorturl │ │ └── Request.php │ ├── APP │ │ └── Params │ │ │ ├── SceneInfo.php │ │ │ ├── Pay │ │ │ └── Request.php │ │ │ └── Client │ │ │ └── Request.php │ ├── CloseOrder │ │ └── Request.php │ ├── AuthCodeToOpenid │ │ └── Request.php │ ├── Notify │ │ ├── Pay.php │ │ ├── PayMode1.php │ │ ├── Refund.php │ │ └── Base.php │ ├── GetPublicKey │ │ └── Request.php │ ├── OrderQuery │ │ └── Request.php │ ├── Reverse │ │ └── Request.php │ ├── Params │ │ ├── GoodsDetail.php │ │ ├── Detail.php │ │ ├── PublicParams.php │ │ └── PayRequestBase.php │ ├── CompanyPay │ │ ├── Bank │ │ │ ├── Query │ │ │ │ └── Request.php │ │ │ └── Pay │ │ │ │ └── Request.php │ │ └── Weixin │ │ │ ├── Query │ │ │ └── Request.php │ │ │ └── Pay │ │ │ └── Request.php │ ├── RefundQuery │ │ └── Request.php │ ├── Micropay │ │ └── Params │ │ │ ├── Pay │ │ │ └── Request.php │ │ │ └── SceneInfo.php │ ├── JSAPI │ │ └── Params │ │ │ ├── Pay │ │ │ └── Request.php │ │ │ ├── JSParams │ │ │ └── Request.php │ │ │ └── SceneInfo.php │ ├── Native │ │ └── Params │ │ │ ├── Pay │ │ │ ├── Request.php │ │ │ └── Mode1Request.php │ │ │ └── SceneInfo.php │ ├── ExchageRate │ │ └── Request.php │ ├── H5 │ │ └── Params │ │ │ ├── Pay │ │ │ └── Request.php │ │ │ └── SceneInfo.php │ ├── DownloadBill │ │ └── Request.php │ ├── QueryComment │ │ └── Request.php │ ├── SettlementQuery │ │ └── Request.php │ ├── Refund │ │ └── Request.php │ ├── CustomDeclareQuery │ │ └── Request.php │ ├── CustomDeclareOrder │ │ └── Request.php │ └── SDK.php ├── Lib │ ├── Encrypt │ │ ├── Base.php │ │ ├── AES.php │ │ ├── DSA.php │ │ ├── RSA.php │ │ └── RSA2.php │ ├── ObjectToArray.php │ └── XML.php ├── AlipayRequestBase.php ├── Traits │ ├── JSONParams.php │ ├── FormParams.php │ └── XMLParams.php ├── PublicBase.php ├── AlipayCrossBorder │ ├── Online │ │ ├── ExchageRate │ │ │ └── Request.php │ │ ├── Notify │ │ │ ├── Sync.php │ │ │ ├── Pay.php │ │ │ └── Base.php │ │ ├── NotifyVerify │ │ │ └── Request.php │ │ ├── DownloadCompare │ │ │ └── Request.php │ │ ├── DownloadSettlement │ │ │ └── Request.php │ │ ├── Query │ │ │ └── Request.php │ │ ├── Refund │ │ │ └── Request.php │ │ ├── Pay │ │ │ └── Request.php │ │ └── WapPay │ │ │ └── Request.php │ ├── InStore │ │ ├── ModifyMerchantQR │ │ │ └── Request.php │ │ ├── CreateMerchantQR │ │ │ ├── ChannelFee.php │ │ │ ├── Request.php │ │ │ └── BizData.php │ │ ├── Query │ │ │ └── Request.php │ │ ├── PreCreate │ │ │ ├── GoodsDetail.php │ │ │ ├── ExtendInfo.php │ │ │ └── Request.php │ │ ├── BarcodePay │ │ │ ├── ExtendInfo.php │ │ │ └── Request.php │ │ ├── Cancel │ │ │ └── Request.php │ │ ├── Refund │ │ │ └── Request.php │ │ ├── ModifyStatus │ │ │ └── Request.php │ │ └── CreateQR │ │ │ └── Request.php │ ├── Customs │ │ ├── Query │ │ │ └── Request.php │ │ └── Submit │ │ │ └── Request.php │ ├── Params │ │ ├── SplitFundInfo.php │ │ └── PublicParams.php │ └── SDK.php ├── AlipayApp │ ├── Params │ │ ├── Close │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ ├── Cancel │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ ├── Query │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ ├── DownloadBill │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ ├── RefundQuery │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ ├── Settle │ │ │ ├── RoyaltyParameter.php │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ ├── Refund │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ │ └── PublicParams.php │ ├── Fund │ │ ├── Query │ │ │ ├── BusinessParams.php │ │ │ └── Request.php │ │ └── Transfer │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ ├── Page │ │ └── Params │ │ │ ├── GoodsDetail.php │ │ │ └── Pay │ │ │ ├── ExtendParams.php │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ ├── FTF │ │ └── Params │ │ │ ├── ExtendParams.php │ │ │ ├── GoodsDetail.php │ │ │ ├── Pay │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ │ │ └── QR │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ ├── App │ │ ├── Params │ │ │ └── Pay │ │ │ │ ├── Request.php │ │ │ │ ├── ExtendParams.php │ │ │ │ └── BusinessParams.php │ │ └── ExtUserInfo.php │ ├── Wap │ │ └── Params │ │ │ └── Pay │ │ │ ├── Request.php │ │ │ ├── ExtendParams.php │ │ │ └── BusinessParams.php │ └── SDK.php ├── RequestBase.php ├── Alipay │ ├── Params │ │ ├── WapPay │ │ │ ├── ExtUserInfo.php │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ │ ├── RefundPwd │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ │ ├── Pay │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ │ ├── Refund │ │ │ ├── Request.php │ │ │ └── BusinessParams.php │ │ └── PublicParams.php │ └── SDK.php ├── WeixinRequestBase.php ├── NotifyBase.php └── Base.php ├── composer.json ├── LICENSE └── README.md /src/Weixin/Reply/Pay.php: -------------------------------------------------------------------------------- 1 | toString(); 9 | } 10 | 11 | public function toString() 12 | { 13 | return \json_encode($this); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Traits/FormParams.php: -------------------------------------------------------------------------------- 1 | toString(); 9 | } 10 | 11 | public function toString() 12 | { 13 | return \http_build_query($this, '', '&'); 14 | } 15 | } -------------------------------------------------------------------------------- /src/PublicBase.php: -------------------------------------------------------------------------------- 1 | toString(); 11 | } 12 | 13 | public function toString() 14 | { 15 | return XML::toString($this); 16 | } 17 | } -------------------------------------------------------------------------------- /src/Weixin/Report/Trades.php: -------------------------------------------------------------------------------- 1 | list); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Weixin/Shorturl/Request.php: -------------------------------------------------------------------------------- 1 | toArray(); 16 | } 17 | else 18 | { 19 | return get_object_vars($object); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yurunsoft/pay-sdk", 3 | "description": "PHP 集成支付 SDK ,集成了支付宝、微信支付的支付接口和其它相关接口的操作。可以轻松嵌入支持 PHP >= 5.4 的任何系统中。", 4 | "type": "library", 5 | "license": "MIT", 6 | "autoload": { 7 | "psr-4": { 8 | "Yurun\\PaySDK\\": "src/" 9 | } 10 | }, 11 | "require": { 12 | "php": "^5.4|^7.0", 13 | "yurunsoft/yurun-http" : "~3.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/ExchageRate/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 20 | } 21 | } -------------------------------------------------------------------------------- /src/Weixin/AuthCodeToOpenid/Request.php: -------------------------------------------------------------------------------- 1 | replyData = new ReplyPay; 22 | } 23 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/Notify/Sync.php: -------------------------------------------------------------------------------- 1 | swooleRequest) 18 | { 19 | return $this->swooleRequest->get; 20 | } 21 | return $_GET; 22 | } 23 | } -------------------------------------------------------------------------------- /src/Weixin/GetPublicKey/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = $this->needAppID = false; 21 | } 22 | } -------------------------------------------------------------------------------- /src/Weixin/Notify/PayMode1.php: -------------------------------------------------------------------------------- 1 | replyData = new ReplyPayMode1; 22 | } 23 | } -------------------------------------------------------------------------------- /src/Weixin/OrderQuery/Request.php: -------------------------------------------------------------------------------- 1 | show_url) 24 | { 25 | return null; 26 | } 27 | return $this->traitToString(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/NotifyVerify/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Weixin/Params/GoodsDetail.php: -------------------------------------------------------------------------------- 1 | notify_id = $this->data['notify_id']; 19 | return 'true' === $this->sdk->execute($request, ''); 20 | } 21 | } -------------------------------------------------------------------------------- /src/RequestBase.php: -------------------------------------------------------------------------------- 1 | sys_service_provider_id) 24 | { 25 | return null; 26 | } 27 | return $this->traitToString(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Alipay/Params/WapPay/ExtUserInfo.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = $this->needSignType = $this->needAppID = false; 27 | } 28 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/RefundQuery/BusinessParams.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 27 | $this->_isSyncVerify = true; 28 | } 29 | } -------------------------------------------------------------------------------- /src/Weixin/CompanyPay/Weixin/Query/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = $this->needSignType = false; 27 | $this->signType = 'MD5'; 28 | } 29 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/DownloadCompare/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 32 | } 33 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/DownloadSettlement/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 32 | } 33 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/Query/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 32 | $this->_isSyncVerify = true; 33 | } 34 | } -------------------------------------------------------------------------------- /src/Weixin/RefundQuery/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 34 | $this->_isSyncVerify = true; 35 | } 36 | } -------------------------------------------------------------------------------- /src/Weixin/Micropay/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | scene_info = new SceneInfo; 33 | parent::__construct(); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Weixin/APP/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | trade_type = 'APP'; 33 | $this->scene_info = new SceneInfo; 34 | parent::__construct(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/Weixin/JSAPI/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | trade_type = 'JSAPI'; 33 | $this->scene_info = new SceneInfo; 34 | parent::__construct(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/Weixin/Native/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | trade_type = 'NATIVE'; 33 | $this->scene_info = new SceneInfo; 34 | parent::__construct(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Params/SplitFundInfo.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 33 | parent::__construct(); 34 | $this->time_stamp = time(); 35 | $this->needSignType = false; 36 | } 37 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/PreCreate/GoodsDetail.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | } 36 | } -------------------------------------------------------------------------------- /src/Weixin/ExchageRate/Request.php: -------------------------------------------------------------------------------- 1 | needNonceStr = $this->needSignType = false; 38 | $this->signType = 'MD5'; 39 | parent::__construct(); 40 | } 41 | } -------------------------------------------------------------------------------- /src/Alipay/Params/RefundPwd/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | } 36 | } -------------------------------------------------------------------------------- /src/Weixin/H5/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | trade_type = 'MWEB'; 39 | $this->scene_info = new SceneInfo; 40 | parent::__construct(); 41 | } 42 | } -------------------------------------------------------------------------------- /src/AlipayApp/Fund/Query/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | } 36 | } -------------------------------------------------------------------------------- /src/Lib/Encrypt/AES.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | } 36 | } -------------------------------------------------------------------------------- /src/AlipayApp/Page/Params/Pay/ExtendParams.php: -------------------------------------------------------------------------------- 1 | sys_service_provider_id && null === $this->hb_fq_num && null === $this->hb_fq_seller_percent) 36 | { 37 | return null; 38 | } 39 | return $this->traitToString(); 40 | } 41 | } -------------------------------------------------------------------------------- /src/Alipay/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 40 | $this->_method = 'GET'; 41 | } 42 | } -------------------------------------------------------------------------------- /src/AlipayApp/Wap/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 40 | $this->_method = 'GET'; 41 | } 42 | } -------------------------------------------------------------------------------- /src/Alipay/Params/WapPay/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 40 | $this->_method = 'GET'; 41 | } 42 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Close/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_trade_close_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Cancel/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_trade_cancel_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Query/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_trade_query_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Weixin/Params/Detail.php: -------------------------------------------------------------------------------- 1 | 33 | */ 34 | public $goods_detail = array(); 35 | 36 | public function toString() 37 | { 38 | if(null === $this->cost_price && null === $this->receipt_id && !isset($this->goods_detail[0])) 39 | { 40 | return null; 41 | } 42 | else 43 | { 44 | return $this->traitToString(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/AlipayApp/Page/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 40 | $this->_method = 'GET'; 41 | } 42 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Refund/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_trade_refund_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Settle/BusinessParams.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | public $royalty_parameters = array(); 28 | 29 | /** 30 | * 操作员id 31 | * @var string 32 | */ 33 | public $operator_id; 34 | 35 | public function toString() 36 | { 37 | $obj = (array)$this; 38 | if(empty($obj['royalty_parameters'])) 39 | { 40 | unset($obj['royalty_parameters']); 41 | } 42 | else 43 | { 44 | $obj['royalty_parameters'] = json_encode($obj['royalty_parameters']); 45 | } 46 | return \json_encode($obj); 47 | } 48 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Settle/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_trade_order_settle_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Alipay/Params/Refund/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 41 | $this->_method = 'GET'; 42 | } 43 | } -------------------------------------------------------------------------------- /src/Weixin/JSAPI/Params/JSParams/Request.php: -------------------------------------------------------------------------------- 1 | $sdk->publicParams->appID, 27 | 'timeStamp' => strval(time()), 28 | 'nonceStr' => md5(mt_rand()), 29 | 'package' => 'prepay_id=' . $this->prepay_id, 30 | 'signType' => $sdk->publicParams->sign_type, 31 | ); 32 | $data['paySign'] = $sdk->sign($data); 33 | $sdk->result = $data; 34 | return true; 35 | } 36 | } -------------------------------------------------------------------------------- /src/Weixin/DownloadBill/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = false; 50 | } 51 | } -------------------------------------------------------------------------------- /src/Weixin/JSAPI/Params/SceneInfo.php: -------------------------------------------------------------------------------- 1 | id && null === $this->name && null === $this->area_code && null === $this->address) 43 | { 44 | return null; 45 | } 46 | else 47 | { 48 | return $this->traitToString(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Weixin/Native/Params/SceneInfo.php: -------------------------------------------------------------------------------- 1 | id && null === $this->name && null === $this->area_code && null === $this->address) 43 | { 44 | return null; 45 | } 46 | else 47 | { 48 | return $this->traitToString(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Weixin/Micropay/Params/SceneInfo.php: -------------------------------------------------------------------------------- 1 | id && null === $this->name && null === $this->area_code && null === $this->address) 43 | { 44 | return null; 45 | } 46 | else 47 | { 48 | return $this->traitToString(); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/RefundQuery/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_trade_fastpay_refund_query_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/PreCreate/ExtendInfo.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 34 | $this->_method = 'GET'; 35 | $this->_isSyncVerify = true; 36 | $this->_syncResponseName = 'alipay_data_dataservice_bill_downloadurl_query_response'; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Weixin/QueryComment/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = false; 49 | $this->needSignType = false; 50 | } 51 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/Refund/BusinessParams.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 44 | $this->_isSyncVerify = true; 45 | } 46 | 47 | public function toArray() 48 | { 49 | $obj = (array)$this; 50 | if(empty($obj['timestamp'])) 51 | { 52 | $obj['timestamp'] = round(\microtime(true) * 1000); 53 | } 54 | return $obj; 55 | } 56 | } -------------------------------------------------------------------------------- /src/WeixinRequestBase.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = true; 58 | } 59 | } -------------------------------------------------------------------------------- /src/AlipayApp/FTF/Params/Pay/Request.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 40 | $this->_method = 'GET'; 41 | $this->_isSyncVerify = true; 42 | $this->_syncResponseName = 'alipay_trade_pay_response'; 43 | } 44 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Params/PublicParams.php: -------------------------------------------------------------------------------- 1 | apiDomain = 'https://mapi.alipay.com/gateway.do'; 56 | } 57 | } -------------------------------------------------------------------------------- /src/Alipay/Params/RefundPwd/BusinessParams.php: -------------------------------------------------------------------------------- 1 | businessParams = new BusinessParams; 40 | $this->_method = 'GET'; 41 | $this->_isSyncVerify = true; 42 | $this->_syncResponseName = 'alipay_trade_precreate_response'; 43 | } 44 | } -------------------------------------------------------------------------------- /src/Weixin/SettlementQuery/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = $this->needSignType = false; 59 | $this->signType = 'MD5'; 60 | } 61 | } -------------------------------------------------------------------------------- /src/Alipay/Params/PublicParams.php: -------------------------------------------------------------------------------- 1 | apiDomain = 'https://mapi.alipay.com/gateway.do'; 56 | } 57 | } -------------------------------------------------------------------------------- /src/AlipayApp/App/ExtUserInfo.php: -------------------------------------------------------------------------------- 1 | replyData = new ReplyPay; 24 | } 25 | 26 | /** 27 | * 获取通知数据 28 | * @return void 29 | */ 30 | public function getNotifyData() 31 | { 32 | $data = parent::getNotifyData(); 33 | if(isset($data['return_code']) && 'SUCCESS' === $data['return_code']) 34 | { 35 | $key = md5($this->sdk->publicParams->key); 36 | $data['req_info'] = XML::fromString(AES::decrypt256($data['req_info'], $key)); 37 | } 38 | return $data; 39 | } 40 | 41 | /** 42 | * 对通知进行验证,是否是正确的通知 43 | * @return bool 44 | */ 45 | public function notifyVerify() 46 | { 47 | return isset($this->data['return_code']); 48 | } 49 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/Refund/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 62 | $this->_isSyncVerify = true; 63 | } 64 | } -------------------------------------------------------------------------------- /src/Weixin/APP/Params/Client/Request.php: -------------------------------------------------------------------------------- 1 | needMchID = false; 49 | $this->needSignType = false; 50 | } 51 | 52 | public function toArray() 53 | { 54 | $data = get_object_vars($this); 55 | if(!isset($data['timestamp'])) 56 | { 57 | $data['timestamp'] = time(); 58 | } 59 | return $data; 60 | } 61 | } -------------------------------------------------------------------------------- /src/AlipayApp/App/Params/Pay/ExtendParams.php: -------------------------------------------------------------------------------- 1 | sys_service_provider_id && null === $this->hb_fq_num && null === $this->hb_fq_seller_percent && null === $this->needBuyerRealnamed && null === $this->TRANS_MEMO) 51 | { 52 | return null; 53 | } 54 | return $this->traitToString(); 55 | } 56 | } -------------------------------------------------------------------------------- /src/AlipayApp/Wap/Params/Pay/ExtendParams.php: -------------------------------------------------------------------------------- 1 | sys_service_provider_id && null === $this->hb_fq_num && null === $this->hb_fq_seller_percent && null === $this->needBuyerRealnamed && null === $this->TRANS_MEMO) 51 | { 52 | return null; 53 | } 54 | return $this->traitToString(); 55 | } 56 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/Notify/Base.php: -------------------------------------------------------------------------------- 1 | swooleResponse) 31 | { 32 | echo $result; 33 | } 34 | else 35 | { 36 | $this->swooleResponse->end($result); 37 | } 38 | } 39 | } 40 | 41 | /** 42 | * 获取通知数据 43 | * @return void 44 | */ 45 | public function getNotifyData() 46 | { 47 | if(null !== $this->swooleRequest) 48 | { 49 | return $this->swooleRequest->post; 50 | } 51 | return $_POST; 52 | } 53 | 54 | /** 55 | * 对通知进行验证,是否是正确的通知 56 | * @return bool 57 | */ 58 | public function notifyVerify() 59 | { 60 | return $this->sdk->verifyCallback($this->data); 61 | } 62 | } -------------------------------------------------------------------------------- /src/AlipayApp/Fund/Transfer/BusinessParams.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 53 | $this->_isSyncVerify = true; 54 | } 55 | 56 | public function toArray() 57 | { 58 | $obj = (array)$this; 59 | if(empty($obj['timestamp'])) 60 | { 61 | $obj['timestamp'] = date('Y-m-d H:i:s'); 62 | } 63 | return $obj; 64 | } 65 | } -------------------------------------------------------------------------------- /src/Lib/XML.php: -------------------------------------------------------------------------------- 1 | '; 24 | if(is_object($data)) 25 | { 26 | $_data = ObjectToArray::parse($data); 27 | } 28 | else 29 | { 30 | $_data = &$data; 31 | } 32 | foreach($_data as $key => $value) 33 | { 34 | if(!\is_scalar($value)) 35 | { 36 | if(\is_object($value) && \method_exists($value, 'toString')) 37 | { 38 | $value = $value->toString(); 39 | if(null === $value) 40 | { 41 | continue; 42 | } 43 | } 44 | else if(null !== $value) 45 | { 46 | $value = \json_encode($value); 47 | } 48 | else 49 | { 50 | continue; 51 | } 52 | } 53 | $result .= "<{$key}>"; 54 | } 55 | return $result . ''; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Weixin/Refund/Request.php: -------------------------------------------------------------------------------- 1 | needSignType = false; 72 | } 73 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/CreateMerchantQR/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 45 | $this->_isSyncVerify = true; 46 | $this->biz_data = new \Yurun\PaySDK\AlipayCrossBorder\InStore\CreateMerchantQR\BizData; 47 | } 48 | 49 | public function toArray() 50 | { 51 | $obj = (array)$this; 52 | if(empty($obj['timestamp'])) 53 | { 54 | $obj['timestamp'] = date('Y-m-d H:i:s'); 55 | } 56 | $obj['biz_data'] = json_encode(ObjectToArray::parse($obj['biz_data'])); 57 | return $obj; 58 | } 59 | } -------------------------------------------------------------------------------- /src/AlipayApp/Params/PublicParams.php: -------------------------------------------------------------------------------- 1 | =5.4.8下才可使用。 26 | * @var string 27 | */ 28 | public $sign_type = 'RSA2'; 29 | 30 | /** 31 | * 调用的接口版本,固定为:1.0 32 | * @var string 33 | */ 34 | public $version = '1.0'; 35 | 36 | /** 37 | * 私有证书文件内容 38 | * @var string 39 | */ 40 | public $appPrivateKey; 41 | 42 | /** 43 | * 私有证书文件地址,不为空时优先使用文件地址 44 | * @var string 45 | */ 46 | public $appPrivateKeyFile; 47 | 48 | /** 49 | * 公有证书文件内容 50 | * @var string 51 | */ 52 | public $appPublicKey; 53 | 54 | /** 55 | * 公有证书文件地址,不为空时优先使用文件地址 56 | * @var string 57 | */ 58 | public $appPublicKeyFile; 59 | 60 | /** 61 | * 是否使用AES加密解密数据 62 | * @var boolean 63 | */ 64 | public $isUseAES = false; 65 | 66 | /** 67 | * AES密钥 68 | * @var string 69 | */ 70 | public $aesKey; 71 | 72 | public function __construct() 73 | { 74 | $this->apiDomain = 'https://openapi.alipay.com/gateway.do'; 75 | } 76 | } -------------------------------------------------------------------------------- /src/Lib/Encrypt/DSA.php: -------------------------------------------------------------------------------- 1 | $this->type, 54 | ); 55 | switch($this->type) 56 | { 57 | case 'IOS': 58 | $data['app_name'] = $this->app_name; 59 | $data['bundle_id'] = $this->bundle_id; 60 | break; 61 | case 'Android': 62 | $data['app_name'] = $this->app_name; 63 | $data['package_name'] = $this->package_name; 64 | break; 65 | case 'Wap': 66 | $data['wap_url'] = $this->wap_url; 67 | $data['wap_name'] = $this->wap_name; 68 | break; 69 | default: 70 | return ''; 71 | } 72 | return json_encode(array('h5_info'=>$data)); 73 | } 74 | } -------------------------------------------------------------------------------- /src/Weixin/Notify/Base.php: -------------------------------------------------------------------------------- 1 | replyData = new ReplyBase; 18 | } 19 | 20 | /** 21 | * 返回数据 22 | * @param boolean $success 23 | * @param string $message 24 | * @return void 25 | */ 26 | public function reply($success, $message = '') 27 | { 28 | $this->replyData->return_code = $success ? 'SUCCESS' : 'FAIL'; 29 | $this->replyData->return_msg = $message; 30 | if(null === $this->swooleResponse) 31 | { 32 | echo $this->replyData; 33 | } 34 | else 35 | { 36 | $this->swooleResponse->end($this->replyData->toString()); 37 | } 38 | } 39 | 40 | /** 41 | * 获取通知数据 42 | * @return void 43 | */ 44 | public function getNotifyData() 45 | { 46 | if(null !== $this->swooleRequest) 47 | { 48 | return XML::fromString($this->swooleRequest->rawContent()); 49 | } 50 | return XML::fromString(\file_get_contents('php://input')); 51 | } 52 | 53 | /** 54 | * 对通知进行验证,是否是正确的通知 55 | * @return bool 56 | */ 57 | public function notifyVerify() 58 | { 59 | return $this->sdk->verifyCallback($this->data); 60 | } 61 | } -------------------------------------------------------------------------------- /src/Weixin/CustomDeclareQuery/Request.php: -------------------------------------------------------------------------------- 1 | needNonceStr = $this->needSignType = false; 64 | $this->signType = 'MD5'; 65 | parent::__construct(); 66 | } 67 | } -------------------------------------------------------------------------------- /src/Weixin/Params/PublicParams.php: -------------------------------------------------------------------------------- 1 | apiDomain = 'https://api.mch.weixin.qq.com/'; 79 | } 80 | } -------------------------------------------------------------------------------- /src/Alipay/Params/Refund/BusinessParams.php: -------------------------------------------------------------------------------- 1 | data = $this->getNotifyData(); 55 | if(!$this->notifyVerify()) 56 | { 57 | $this->reply(false, '通知不合法'); 58 | throw new \Exception('通知不合法'); 59 | } 60 | $this->__exec(); 61 | } 62 | 63 | /** 64 | * 返回数据 65 | * @param boolean $success 66 | * @param string $message 67 | * @return void 68 | */ 69 | public abstract function reply($success, $message = ''); 70 | 71 | /** 72 | * 获取通知数据 73 | * @return void 74 | */ 75 | public abstract function getNotifyData(); 76 | 77 | /** 78 | * 对通知进行验证,是否是正确的通知 79 | * @return bool 80 | */ 81 | public abstract function notifyVerify(); 82 | 83 | /** 84 | * 后续执行操作 85 | * @return void 86 | */ 87 | protected abstract function __exec(); 88 | } -------------------------------------------------------------------------------- /src/Weixin/CompanyPay/Weixin/Pay/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = $this->needSignType = false; 84 | $this->signType = 'MD5'; 85 | } 86 | } -------------------------------------------------------------------------------- /src/Weixin/CompanyPay/Bank/Pay/Request.php: -------------------------------------------------------------------------------- 1 | _isSyncVerify = $this->needSignType = $this->needAppID = false; 64 | } 65 | 66 | public function toArray() 67 | { 68 | $data = get_object_vars($this); 69 | $data['enc_bank_no'] = \base64_encode(RSA::encryptPublicFromFile($data['enc_bank_no'], $this->rsaPublicCertFile)); 70 | $data['enc_true_name'] = \base64_encode(RSA::encryptPublicFromFile($data['enc_true_name'], $this->rsaPublicCertFile)); 71 | return $data; 72 | } 73 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Customs/Submit/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 82 | $this->_isSyncVerify = true; 83 | } 84 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/Refund/Request.php: -------------------------------------------------------------------------------- 1 | 70 | */ 71 | public $split_fund_info = array(); 72 | 73 | public function __construct() 74 | { 75 | $this->_method = 'GET'; 76 | $this->_isSyncVerify = true; 77 | } 78 | 79 | public function toArray() 80 | { 81 | $obj = (array)$this; 82 | if(empty($obj['split_fund_info'])) 83 | { 84 | unset($obj['split_fund_info']); 85 | } 86 | else 87 | { 88 | $obj['split_fund_info'] = json_encode($obj['split_fund_info']); 89 | } 90 | return $obj; 91 | } 92 | } -------------------------------------------------------------------------------- /src/Lib/Encrypt/RSA.php: -------------------------------------------------------------------------------- 1 | =5.4.8下才可使用'); 11 | } 12 | $key = static::parseKey($key); 13 | $key = "-----BEGIN RSA PRIVATE KEY-----\n{$key}\n-----END RSA PRIVATE KEY-----"; 14 | openssl_sign($data, $sign, $key, OPENSSL_ALGO_SHA256); 15 | return $sign; 16 | } 17 | 18 | public static function signPrivateFromFile($data, $fileName) 19 | { 20 | if(!defined('OPENSSL_ALGO_SHA256')) 21 | { 22 | throw new \Exception('SHA256需要在PHP>=5.4.8下才可使用'); 23 | } 24 | $key = file_get_contents($fileName); 25 | $res = openssl_get_privatekey($key); 26 | if(!$res) 27 | { 28 | throw new \Exception('私钥文件格式错误'); 29 | } 30 | openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); 31 | openssl_free_key($res); 32 | return $sign; 33 | } 34 | 35 | public static function verifyPublic($data, $key, $sign) 36 | { 37 | if(!defined('OPENSSL_ALGO_SHA256')) 38 | { 39 | throw new \Exception('SHA256需要在PHP>=5.4.8下才可使用'); 40 | } 41 | $key = static::parseKey($key); 42 | $key = "-----BEGIN PUBLIC KEY-----\n{$key}\n-----END PUBLIC KEY-----"; 43 | return 1 === openssl_verify($data, $sign, $key, OPENSSL_ALGO_SHA256); 44 | } 45 | 46 | public static function verifyPublicFromFile($data, $fileName, $sign) 47 | { 48 | if(!defined('OPENSSL_ALGO_SHA256')) 49 | { 50 | throw new \Exception('SHA256需要在PHP>=5.4.8下才可使用'); 51 | } 52 | $key = file_get_contents($fileName); 53 | $res = openssl_get_publickey($key); 54 | if(!$res) 55 | { 56 | throw new \Exception('公钥文件格式错误'); 57 | } 58 | $result = openssl_verify($data, $sign, $res, OPENSSL_ALGO_SHA256); 59 | openssl_free_key($res); 60 | return 1 === $result; 61 | } 62 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/BarcodePay/Request.php: -------------------------------------------------------------------------------- 1 | _method = 'GET'; 94 | $this->_isSyncVerify = true; 95 | $this->extend_info = new ExtendInfo; 96 | } 97 | 98 | public function toArray() 99 | { 100 | $obj = (array)$this; 101 | if(empty($obj['extend_info'])) 102 | { 103 | unset($obj['extend_info']); 104 | } 105 | else 106 | { 107 | $obj['extend_info'] = json_encode($obj['extend_info']); 108 | } 109 | return $obj; 110 | } 111 | } -------------------------------------------------------------------------------- /src/Weixin/Report/Request.php: -------------------------------------------------------------------------------- 1 | allowReport = false; 119 | $this->_isSyncVerify = false; 120 | } 121 | } -------------------------------------------------------------------------------- /src/Weixin/CustomDeclareOrder/Request.php: -------------------------------------------------------------------------------- 1 | needNonceStr = $this->needSignType = false; 116 | $this->signType = 'MD5'; 117 | parent::__construct(); 118 | } 119 | } -------------------------------------------------------------------------------- /src/AlipayApp/FTF/Params/QR/BusinessParams.php: -------------------------------------------------------------------------------- 1 | 54 | */ 55 | public $goods_detail; 56 | 57 | /** 58 | * 业务扩展参数,详见业务扩展参数说明 59 | * @var \Yurun\PaySDK\AlipayApp\FTF\Params\ExtendParams 60 | */ 61 | public $extend_params; 62 | 63 | /** 64 | * 商户操作员编号 65 | * @var string 66 | */ 67 | public $operator_id; 68 | 69 | /** 70 | * 商户门店编号 71 | * @var string 72 | */ 73 | public $store_id; 74 | 75 | /** 76 | * 商户机具终端编号 77 | * @var string 78 | */ 79 | public $terminal_id; 80 | 81 | /** 82 | * 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m 83 | * @var string 84 | */ 85 | public $timeout_express; 86 | 87 | public function __construct() 88 | { 89 | $this->extend_params = new ExtendParams; 90 | } 91 | 92 | public function toString() 93 | { 94 | $obj = (array)$this; 95 | if(empty($obj['goods_detail'])) 96 | { 97 | unset($obj['goods_detail']); 98 | } 99 | else 100 | { 101 | $obj['goods_detail'] = json_encode($obj['goods_detail']); 102 | } 103 | $result = $obj['extend_params']->toString(); 104 | if(null === $result) 105 | { 106 | unset($obj['extend_params']); 107 | } 108 | else 109 | { 110 | $obj['extend_params'] = $result; 111 | } 112 | foreach($obj as $key => $value) 113 | { 114 | if(null === $value) 115 | { 116 | unset($obj[$key]); 117 | } 118 | } 119 | return \json_encode($obj); 120 | } 121 | } -------------------------------------------------------------------------------- /src/Weixin/Params/PayRequestBase.php: -------------------------------------------------------------------------------- 1 | detail = new Detail; 109 | } 110 | } -------------------------------------------------------------------------------- /src/AlipayApp/App/Params/Pay/BusinessParams.php: -------------------------------------------------------------------------------- 1 | extend_params = new ExtendParams; 106 | } 107 | 108 | public function toString() 109 | { 110 | $obj = (array)$this; 111 | $result = $obj['extend_params']->toString(); 112 | if(null === $result) 113 | { 114 | unset($obj['extend_params']); 115 | } 116 | else 117 | { 118 | $obj['extend_params'] = $result; 119 | } 120 | foreach($obj as $key => $value) 121 | { 122 | if(null === $value) 123 | { 124 | unset($obj[$key]); 125 | } 126 | } 127 | return \json_encode($obj); 128 | } 129 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/CreateMerchantQR/BizData.php: -------------------------------------------------------------------------------- 1 | channel_fee = new \Yurun\PaySDK\AlipayCrossBorder\InStore\CreateMerchantQR\ChannelFee; 131 | } 132 | 133 | public function toArray() 134 | { 135 | $obj = (array)$this; 136 | if(empty($obj['passback_parameters'])) 137 | { 138 | unset($obj['passback_parameters']); 139 | } 140 | if(empty($obj['channel_fee']->type)) 141 | { 142 | unset($obj['channel_fee']); 143 | } 144 | foreach($obj as $key => $value) 145 | { 146 | if(null === $value) 147 | { 148 | unset($obj[$key]); 149 | } 150 | } 151 | return $obj; 152 | } 153 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/Pay/Request.php: -------------------------------------------------------------------------------- 1 | 125 | */ 126 | public $split_fund_info = array(); 127 | 128 | public function __construct() 129 | { 130 | $this->_method = 'GET'; 131 | } 132 | 133 | public function toArray() 134 | { 135 | $obj = (array)$this; 136 | if(empty($obj['split_fund_info'])) 137 | { 138 | unset($obj['split_fund_info']); 139 | } 140 | else 141 | { 142 | $obj['split_fund_info'] = json_encode($obj['split_fund_info']); 143 | } 144 | return $obj; 145 | } 146 | } -------------------------------------------------------------------------------- /src/AlipayApp/Wap/Params/Pay/BusinessParams.php: -------------------------------------------------------------------------------- 1 | extend_params = new ExtendParams; 119 | } 120 | 121 | public function toString() 122 | { 123 | $obj = (array)$this; 124 | $result = $obj['extend_params']->toString(); 125 | if(null === $result) 126 | { 127 | unset($obj['extend_params']); 128 | } 129 | else 130 | { 131 | $obj['extend_params'] = $result; 132 | } 133 | foreach($obj as $key => $value) 134 | { 135 | if(null === $value) 136 | { 137 | unset($obj[$key]); 138 | } 139 | } 140 | return \json_encode($obj); 141 | } 142 | } -------------------------------------------------------------------------------- /src/AlipayApp/FTF/Params/Pay/BusinessParams.php: -------------------------------------------------------------------------------- 1 | 80 | */ 81 | public $goods_detail; 82 | 83 | /** 84 | * 业务扩展参数,详见业务扩展参数说明 85 | * @var \Yurun\PaySDK\AlipayApp\FTF\Params\ExtendParams 86 | */ 87 | public $extend_params; 88 | 89 | /** 90 | * 商户操作员编号 91 | * @var string 92 | */ 93 | public $operator_id; 94 | 95 | /** 96 | * 商户门店编号 97 | * @var string 98 | */ 99 | public $store_id; 100 | 101 | /** 102 | * 商户机具终端编号 103 | * @var string 104 | */ 105 | public $terminal_id; 106 | 107 | /** 108 | * 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m 109 | * @var string 110 | */ 111 | public $timeout_express; 112 | 113 | public function __construct() 114 | { 115 | $this->extend_params = new ExtendParams; 116 | } 117 | 118 | public function toString() 119 | { 120 | $obj = (array)$this; 121 | if(empty($obj['goods_detail'])) 122 | { 123 | unset($obj['goods_detail']); 124 | } 125 | else 126 | { 127 | $obj['goods_detail'] = json_encode($obj['goods_detail']); 128 | } 129 | $result = $obj['extend_params']->toString(); 130 | if(null === $result) 131 | { 132 | unset($obj['extend_params']); 133 | } 134 | else 135 | { 136 | $obj['extend_params'] = $result; 137 | } 138 | foreach($obj as $key => $value) 139 | { 140 | if(null === $value) 141 | { 142 | unset($obj[$key]); 143 | } 144 | } 145 | return \json_encode($obj); 146 | } 147 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/Online/WapPay/Request.php: -------------------------------------------------------------------------------- 1 | 130 | */ 131 | public $split_fund_info = array(); 132 | 133 | public function __construct() 134 | { 135 | $this->_method = 'GET'; 136 | } 137 | 138 | public function toArray() 139 | { 140 | $obj = (array)$this; 141 | if(empty($obj['split_fund_info'])) 142 | { 143 | unset($obj['split_fund_info']); 144 | } 145 | else 146 | { 147 | $obj['split_fund_info'] = json_encode($obj['split_fund_info']); 148 | } 149 | return $obj; 150 | } 151 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/PreCreate/Request.php: -------------------------------------------------------------------------------- 1 | 112 | */ 113 | public $goods_detail = array(); 114 | 115 | /** 116 | * 用于传送商家的具体业务信息;如果商家和支付宝同意传输此参数并就该参数的含义达成协议, 则此参数才有效。 117 | * 例如, 在可以通过声波进行付款的情况下, 存储 ID 和其他信息;此类资料应以 json 格式写成;有关详细信息, 请参阅 "4.4 业务扩展参数说明"。 118 | * @var \Yurun\PaySDK\AlipayCrossBorder\InStore\PreCreate\ExtendInfo 119 | */ 120 | public $extend_params; 121 | 122 | /** 123 | * 设置逾期不付款的交易, 贸易将自动关闭一旦时间。 124 | * 值的范围: 1 m ~ 15 d。 125 | * m 分钟, h 小时, d-day, 1 c-当前天 (每当贸易被创造, 它将被关闭在 0:00)。 126 | * 此参数的数值 Demical 点被拒绝, 例如, 1.5h 可以 tansformed 到90m。 127 | * 为了实现这一功能, 支付宝需要被建议设置关闭时间。 128 | * @var string 129 | */ 130 | public $it_b_pay; 131 | 132 | /** 133 | * 如果商家通过请求字符串传输此参数, 支付宝将通过异步通知 (参数名称: extra_common_param) 来反馈此参数。 134 | * @var string 135 | */ 136 | public $passback_parameters; 137 | 138 | public function __construct() 139 | { 140 | $this->_method = 'GET'; 141 | $this->_isSyncVerify = true; 142 | $this->goods_detail = array(); 143 | $this->extend_params = new ExtendInfo; 144 | } 145 | 146 | public function toArray() 147 | { 148 | $obj = (array)$this; 149 | if(empty($obj['timestamp'])) 150 | { 151 | $obj['timestamp'] = round(\microtime(true) * 1000); 152 | } 153 | if(empty($obj['goods_detail'])) 154 | { 155 | unset($obj['goods_detail']); 156 | } 157 | else 158 | { 159 | $obj['goods_detail'] = json_encode($obj['goods_detail']); 160 | } 161 | $obj['extend_params'] = json_encode($obj['extend_params']); 162 | return $obj; 163 | } 164 | } -------------------------------------------------------------------------------- /src/AlipayApp/Page/Params/Pay/BusinessParams.php: -------------------------------------------------------------------------------- 1 | goods_detail = new GoodsDetail; 120 | $this->extend_params = new ExtendParams; 121 | } 122 | 123 | public function toString() 124 | { 125 | $obj = (array)$this; 126 | $result = $obj['goods_detail']->toString(); 127 | if(null === $result) 128 | { 129 | unset($obj['goods_detail']); 130 | } 131 | else 132 | { 133 | $obj['goods_detail'] = $result; 134 | } 135 | $result = $obj['extend_params']->toString(); 136 | if(null === $result) 137 | { 138 | unset($obj['extend_params']); 139 | } 140 | else 141 | { 142 | $obj['extend_params'] = $result; 143 | } 144 | foreach($obj as $key => $value) 145 | { 146 | if(null === $value) 147 | { 148 | unset($obj[$key]); 149 | } 150 | } 151 | return \json_encode($obj); 152 | } 153 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/InStore/CreateQR/Request.php: -------------------------------------------------------------------------------- 1 | 118 | */ 119 | public $goods_detail = array(); 120 | 121 | /** 122 | * 用于传送商家的具体业务信息;如果商家和支付宝同意传输此参数并就该参数的含义达成协议, 则此参数才有效。 123 | * 例如, 在可以通过声波进行付款的情况下, 存储 ID 和其他信息;此类资料应以 json 格式写成;有关详细信息, 请参阅 "4.4 业务扩展参数说明"。 124 | * @var \Yurun\PaySDK\AlipayCrossBorder\InStore\PreCreate\ExtendInfo 125 | */ 126 | public $extend_params; 127 | 128 | /** 129 | * 设置逾期不付款的交易, 贸易将自动关闭一旦时间。 130 | * 值的范围: 1 m ~ 15 d。 131 | * m 分钟, h 小时, d-day, 1 c-当前天 (每当贸易被创造, 它将被关闭在 0:00)。 132 | * 此参数的数值 Demical 点被拒绝, 例如, 1.5h 可以 tansformed 到90m。 133 | * 为了实现这一功能, 支付宝需要被建议设置关闭时间。 134 | * @var string 135 | */ 136 | public $it_b_pay; 137 | 138 | /** 139 | * 如果商家通过请求字符串传输此参数, 支付宝将通过异步通知 (参数名称: extra_common_param) 来反馈此参数。 140 | * @var string 141 | */ 142 | public $passback_parameters; 143 | 144 | /** 145 | * 商户服务器发送请求的时间戳, 精确到毫秒 146 | * @var int 147 | */ 148 | public $timestamp; 149 | 150 | public function __construct() 151 | { 152 | $this->_method = 'GET'; 153 | $this->_isSyncVerify = true; 154 | $this->extend_params = new \Yurun\PaySDK\AlipayCrossBorder\InStore\PreCreate\ExtendInfo; 155 | } 156 | 157 | public function toArray() 158 | { 159 | $obj = (array)$this; 160 | if(empty($obj['timestamp'])) 161 | { 162 | $obj['timestamp'] = round(\microtime(true) * 1000); 163 | } 164 | if(empty($obj['goods_detail'])) 165 | { 166 | unset($obj['goods_detail']); 167 | } 168 | $obj['extend_params'] = (array)$obj['extend_params']; 169 | foreach($obj['extend_params'] as $key => $value) 170 | { 171 | if(null === $value) 172 | { 173 | unset($obj['extend_params'][$key]); 174 | } 175 | } 176 | $obj['extend_params'] = json_encode($obj['extend_params']); 177 | return $obj; 178 | } 179 | } -------------------------------------------------------------------------------- /src/Alipay/Params/Pay/BusinessParams.php: -------------------------------------------------------------------------------- 1 | = 5.4 的任何系统中,2.0 版现已支持 Swoole 协程环境。 10 | 11 | 我们有完善的在线技术文档:[http://doc.yurunsoft.com/PaySDK](http://doc.yurunsoft.com/PaySDK) 12 | 13 | API 文档:[https://apidoc.gitee.com/yurunsoft/PaySDK](https://apidoc.gitee.com/yurunsoft/PaySDK) 14 | 15 | 同时欢迎各位加入技术支持群:74401592 [![点击加群](https://pub.idqqimg.com/wpa/images/group.png "点击加群")](https://shang.qq.com/wpa/qunwpa?idkey=e2e6b49e9a648aae5285b3aba155d59107bb66fde02e229e078bd7359cac8ac3),如有问题可以及时解答和修复。 16 | 17 | 大家在开发中肯定会对接各种各样的支付平台,我个人精力有限,欢迎各位来提交 PR ([码云](https://gitee.com/yurunsoft/PaySDK)/[Github](https://github.com/Yurunsoft/PaySDK)),一起完善 PaySDK ,让它能够支持更多的支付平台,更加好用。 18 | 19 | 有许多朋友表示不敢用这类 SDK ,在这我再声明一下: PaySDK 是基于 MIT 协议开源的,你可以阅读修改所有无压缩无加密的源代码,绝对不会留任何后门。 20 | 21 | ## 支持的支付接口 22 | 23 | ### 支付宝 24 | * 即时到账-电脑网站支付(老) 25 | * 即时到账-手机网站支付(老) 26 | * 当面付 27 | * 手机网站支付 28 | * 电脑网站支付 29 | * APP支付服务端 30 | * 单笔转账到支付宝账户 31 | * 海外支付(电脑网站、手机网站、APP、扫码) 32 | * 海关报关 33 | * 其它辅助交易接口(退款、查询等) 34 | 35 | ### 微信支付 36 | * 刷卡支付 37 | * 公众号支付 38 | * 扫码支付 39 | * APP支付 40 | * H5支付 41 | * 小程序支付 42 | * 企业付款到零钱 43 | * 企业付款到银行卡 44 | * 海外支付(刷卡、公众号、扫码、APP) 45 | * 海关报关 46 | * 其它辅助交易接口(退款、查询等) 47 | 48 | ## 安装 49 | 50 | 在您的composer.json中加入配置: 51 | 52 | ```json 53 | { 54 | "require": { 55 | "yurunsoft/pay-sdk": "~2.0" 56 | } 57 | } 58 | ``` 59 | 60 | 然后执行`composer update`命令。 61 | 62 | ## 代码示例 63 | 64 | ### 支付宝即时到账 65 | 66 | ```php 67 | // SDK实例化,传入公共配置 68 | $pay = new \Yurun\PaySDK\Alipay\SDK($params); 69 | 70 | // 支付接口 71 | $request = new \Yurun\PaySDK\Alipay\Params\Pay\Request; 72 | $request->notify_url = ''; // 支付后通知地址(作为支付成功回调,这个可靠) 73 | $request->return_url = ''; // 支付后跳转返回地址 74 | $request->businessParams->seller_id = $GLOBALS['PAY_CONFIG']['appid']; // 卖家支付宝用户号 75 | $request->businessParams->out_trade_no = 'test' . mt_rand(10000000,99999999); // 商户订单号 76 | $request->businessParams->total_fee = 0.01; // 价格 77 | $request->businessParams->subject = '测试商品'; // 商品标题 78 | 79 | // 跳转到支付宝页面 80 | $pay->redirectExecute($request); 81 | ``` 82 | 83 | ### 支付宝手机网站支付 84 | 85 | ```php 86 | // SDK实例化,传入公共配置 87 | $pay = new \Yurun\PaySDK\AlipayApp\SDK($params); 88 | 89 | // 支付接口 90 | $request = new \Yurun\PaySDK\AlipayApp\Wap\Params\Pay\Request; 91 | $request->notify_url = ''; // 支付后通知地址(作为支付成功回调,这个可靠) 92 | $request->return_url = ''; // 支付后跳转返回地址 93 | $request->businessParams->out_trade_no = 'test' . mt_rand(10000000,99999999); // 商户订单号 94 | $request->businessParams->total_amount = 0.01; // 价格 95 | $request->businessParams->subject = '小米手机9黑色陶瓷尊享版'; // 商品标题 96 | 97 | // 跳转到支付宝页面 98 | $pay->redirectExecute($request); 99 | ``` 100 | 101 | ### 微信H5支付 102 | 103 | ```php 104 | // SDK实例化,传入公共配置 105 | $pay = new \Yurun\PaySDK\Weixin\SDK($params); 106 | 107 | // 支付接口 108 | $request = new \Yurun\PaySDK\Weixin\H5\Params\Pay\Request; 109 | $request->body = 'test'; // 商品描述 110 | $request->out_trade_no = 'test' . mt_rand(10000000,99999999); // 订单号 111 | $request->total_fee = 1; // 订单总金额,单位为:分 112 | $request->spbill_create_ip = '127.0.0.1'; // 客户端ip 113 | $request->notify_url = ''; // 异步通知地址 114 | 115 | // 调用接口 116 | $result = $pay->execute($request); 117 | if($pay->checkResult()) 118 | { 119 | // 跳转支付界面 120 | header('Location: ' . $result['mweb_url']); 121 | } 122 | else 123 | { 124 | var_dump($pay->getErrorCode() . ':' . $pay->getError()); 125 | } 126 | exit; 127 | ``` 128 | 129 | ### Swoole 协程环境支持 130 | 131 | ```php 132 | \Yurun\Util\YurunHttp::setDefaultHandler('Yurun\Util\YurunHttp\Handler\Swoole'); 133 | ``` 134 | 135 | ## 捐赠 136 | 137 | 138 | 139 | 开源不求盈利,多少都是心意,生活不易,随缘随缘…… -------------------------------------------------------------------------------- /src/Alipay/Params/WapPay/BusinessParams.php: -------------------------------------------------------------------------------- 1 | ext_user_info = new ExtUserInfo; 176 | } 177 | 178 | public function toArray() 179 | { 180 | $obj = (array)$this; 181 | $result = $obj['ext_user_info']->toString(); 182 | if(null === $result) 183 | { 184 | unset($obj['ext_user_info']); 185 | } 186 | else 187 | { 188 | $obj['ext_user_info'] = $result; 189 | } 190 | foreach($obj as $key => $value) 191 | { 192 | if(null === $value) 193 | { 194 | unset($obj[$key]); 195 | } 196 | } 197 | return $obj; 198 | } 199 | } -------------------------------------------------------------------------------- /src/Alipay/SDK.php: -------------------------------------------------------------------------------- 1 | publicParams), ObjectToArray::parse($params), ObjectToArray::parse($params->businessParams)); 29 | unset($data['apiDomain'], $data['appID'], $data['businessParams'], $data['appPrivateKey'], $data['appPrivateKeyFile'], $data['md5Key'], $data['appPublicKey'], $data['appPublicKeyFile'], $data['_syncResponseName'], $data['_method'], $data['_isSyncVerify']); 30 | $data['partner'] = $this->publicParams->appID; 31 | foreach($data as $key => $value) 32 | { 33 | if('' == $value) 34 | { 35 | unset($data[$key]); 36 | } 37 | } 38 | $data['sign'] = $this->sign($data); 39 | $requestData = $data; 40 | $url = $this->publicParams->apiDomain; 41 | } 42 | 43 | public function sign($data) 44 | { 45 | $content = $this->parseSignData($data); 46 | if(empty($this->publicParams->appPrivateKeyFile)) 47 | { 48 | $key = $this->publicParams->appPrivateKey; 49 | $method = 'signPrivate'; 50 | } 51 | else 52 | { 53 | $key = $this->publicParams->appPrivateKeyFile; 54 | $method = 'signPrivateFromFile'; 55 | } 56 | switch($this->publicParams->sign_type) 57 | { 58 | case 'DSA': 59 | $result = \Yurun\PaySDK\Lib\Encrypt\DSA::$method($content, $key); 60 | break; 61 | case 'RSA': 62 | $result = \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key); 63 | break; 64 | case 'MD5': 65 | return md5($content . $this->publicParams->md5Key); 66 | default: 67 | throw new \Exception('未知的加密方式:' . $this->publicParams->sign_type); 68 | } 69 | return \base64_encode($result); 70 | } 71 | 72 | /** 73 | * 验证回调通知是否合法 74 | * @param $data 75 | * @return bool 76 | */ 77 | public function verifyCallback($data) 78 | { 79 | if(!isset($data['sign'], $data['sign_type'])) 80 | { 81 | return false; 82 | } 83 | $content = $this->parseSignData($data); 84 | if(empty($this->publicParams->appPublicKeyFile)) 85 | { 86 | $key = $this->publicParams->appPublicKey; 87 | $method = 'verifyPublic'; 88 | } 89 | else 90 | { 91 | $key = $this->publicParams->appPublicKeyFile; 92 | $method = 'verifyPublicFromFile'; 93 | } 94 | switch($this->publicParams->sign_type) 95 | { 96 | case 'DSA': 97 | return \Yurun\PaySDK\Lib\Encrypt\DSA::$method($content, $key, \base64_decode($data['sign'])); 98 | case 'RSA': 99 | return \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key, \base64_decode($data['sign'])); 100 | case 'MD5': 101 | return $data['sign'] === md5($content . $this->publicParams->md5Key); 102 | default: 103 | throw new \Exception('未知的加密方式:' . $this->publicParams->sign_type); 104 | } 105 | } 106 | 107 | /** 108 | * 验证同步返回内容 109 | * @param AlipayRequestBase $params 110 | * @param array $data 111 | * @return bool 112 | */ 113 | public function verifySync($params, $data) 114 | { 115 | return true; 116 | } 117 | 118 | public function parseSignData($data) 119 | { 120 | unset($data['sign_type'], $data['sign']); 121 | \ksort($data); 122 | $content = ''; 123 | foreach ($data as $k => $v){ 124 | if($v !== '' && $v !== null && !is_array($v)){ 125 | $content .= $k . '=' . $v . '&'; 126 | } 127 | } 128 | return trim($content, '&'); 129 | } 130 | 131 | /** 132 | * 调用执行接口 133 | * @param mixed $params 134 | * @param string $method 135 | * @return mixed 136 | */ 137 | public function execute($params, $format = 'XML') 138 | { 139 | $result = parent::execute($params, $format); 140 | return $result; 141 | } 142 | 143 | /** 144 | * 检查是否执行成功 145 | * @param array $result 146 | * @return boolean 147 | */ 148 | protected function __checkResult($result) 149 | { 150 | return true; 151 | } 152 | 153 | /** 154 | * 获取错误信息 155 | * @param array $result 156 | * @return string 157 | */ 158 | protected function __getError($result) 159 | { 160 | return ''; 161 | } 162 | 163 | /** 164 | * 获取错误代码 165 | * @param array $result 166 | * @return string 167 | */ 168 | protected function __getErrorCode($result) 169 | { 170 | return ''; 171 | } 172 | } -------------------------------------------------------------------------------- /src/Base.php: -------------------------------------------------------------------------------- 1 | publicParams = $publicParams; 65 | $this->http = new HttpRequest; 66 | } 67 | 68 | /** 69 | * 调用执行接口 70 | * @param mixed $params 71 | * @param string $method 72 | * @return mixed 73 | */ 74 | public function execute($params, $format = 'JSON') 75 | { 76 | if($params->__onExecute($this, $format)) 77 | { 78 | return $this->result; 79 | } 80 | $this->prepareExecute($params, $url, $data); 81 | $this->url = $url; 82 | $this->response = $this->http->send($url, $this->requestData, $params->_method); 83 | switch($format) 84 | { 85 | case 'JSON': 86 | $this->result = $this->response->json(true); 87 | break; 88 | case 'XML': 89 | $this->result = XML::fromString($this->response->body()); 90 | break; 91 | default: 92 | $this->result = $this->response->body(); 93 | } 94 | if($params->_isSyncVerify && !$this->verifySync($params, $this->result)) 95 | { 96 | throw new \Exception('同步返回数据验证失败'); 97 | } 98 | else 99 | { 100 | return $this->result; 101 | } 102 | } 103 | 104 | /** 105 | * 调用执行接口,将结果保存至文件 106 | * @param mixed $params 107 | * @param string $saveFilename 108 | * @return void 109 | */ 110 | public function executeDownload($params, $saveFilename) 111 | { 112 | $this->prepareExecute($params, $url, $data); 113 | $this->url = $url; 114 | $this->http->saveFile($saveFilename)->send($url, $this->requestData, $params->_method); 115 | } 116 | 117 | /** 118 | * 签名 119 | * @param array $data 120 | * @return string 121 | */ 122 | public abstract function sign($data); 123 | 124 | /** 125 | * 处理执行接口的数据 126 | * @param $params 127 | * @param &$data 数据数组 128 | * @param &$requestData 请求用的数据,格式化后的 129 | * @param &$url 请求地址 130 | * @return array 131 | */ 132 | public abstract function __parseExecuteData($params, &$data, &$requestData, &$url); 133 | 134 | /** 135 | * 验证回调通知是否合法 136 | * @param $data 137 | * @return bool 138 | */ 139 | public abstract function verifyCallback($data); 140 | 141 | /** 142 | * 验证同步返回内容 143 | * @param mixed $params 144 | * @param array $data 145 | * @return bool 146 | */ 147 | public abstract function verifySync($params, $data); 148 | 149 | /** 150 | * 检查是否执行成功 151 | * @param array $result 152 | * @return boolean 153 | */ 154 | protected abstract function __checkResult($result); 155 | 156 | /** 157 | * 获取错误信息 158 | * @param array $result 159 | * @return string 160 | */ 161 | protected abstract function __getError($result); 162 | 163 | /** 164 | * 获取错误代码 165 | * @param array $result 166 | * @return string 167 | */ 168 | protected abstract function __getErrorCode($result); 169 | 170 | /** 171 | * 检查是否执行成功 172 | * @param array $result 173 | * @return boolean 174 | */ 175 | public function checkResult($result = null) 176 | { 177 | return $this->__checkResult(null === $result ? $this->result : $result); 178 | } 179 | 180 | /** 181 | * 获取错误信息 182 | * @param array $result 183 | * @return string 184 | */ 185 | public function getError($result = null) 186 | { 187 | return $this->__getError(null === $result ? $this->result : $result); 188 | } 189 | 190 | /** 191 | * 获取错误代码 192 | * @param array $result 193 | * @return string 194 | */ 195 | public function getErrorCode($result = null) 196 | { 197 | return $this->__getErrorCode(null === $result ? $this->result : $result); 198 | } 199 | 200 | /** 201 | * 使用跳转的方式处理 202 | * @param array $params 203 | * @return void 204 | */ 205 | public function redirectExecute($params) 206 | { 207 | $this->__parseExecuteData($params, $data, $requestData, $url); 208 | if(false === strpos($url, '?')) 209 | { 210 | $url .= '?'; 211 | } 212 | else 213 | { 214 | $url .= '&'; 215 | } 216 | $this->requestData = $data; 217 | $url .= \http_build_query($data, '', '&'); 218 | if(null === $this->swooleResponse) 219 | { 220 | header('HTTP/1.1 302 Temporarily Moved'); 221 | header('Status: 302 Temporarily Moved'); 222 | header('Location: ' . $url); 223 | exit; 224 | } 225 | else 226 | { 227 | $this->swooleResponse->redirect($url, 302); 228 | } 229 | } 230 | 231 | /** 232 | * 准备处理数据 233 | * @param string $params 234 | * @param string $url 235 | * @param array $data 236 | * @return void 237 | */ 238 | public function prepareExecute($params, &$url = null, &$data = null) 239 | { 240 | $this->__parseExecuteData($params, $data, $requestData, $url); 241 | $this->requestData = $requestData; 242 | if('GET' === $params->_method) 243 | { 244 | if(false === strpos($url, '?')) 245 | { 246 | $url .= '?'; 247 | } 248 | else 249 | { 250 | $url .= '&'; 251 | } 252 | $url .= \http_build_query($data, '', '&'); 253 | } 254 | } 255 | 256 | /** 257 | * 处理异步通知 258 | * @param mixed $notifyHandle 259 | * @return void 260 | */ 261 | public function notify($notifyHandle) 262 | { 263 | $notifyHandle->sdk = $this; 264 | $notifyHandle->exec(); 265 | } 266 | } -------------------------------------------------------------------------------- /src/AlipayApp/SDK.php: -------------------------------------------------------------------------------- 1 | publicParams), ObjectToArray::parse($params)); 30 | unset($data['apiDomain'], $data['appID'], $data['businessParams'], $data['appPrivateKey'], $data['appPrivateKeyFile'], $data['appPublicKey'], $data['appPublicKeyFile'], $data['_syncResponseName'], $data['_method'], $data['_isSyncVerify'], $data['aesKey'], $data['isUseAES']); 31 | $data['app_id'] = $this->publicParams->appID; 32 | $data['biz_content'] = $params->businessParams->toString(); 33 | if($this->publicParams->isUseAES) 34 | { 35 | $data['biz_content'] = AES::encrypt($data['biz_content'], \base64_decode($this->publicParams->aesKey)); 36 | } 37 | $data['timestamp'] = date('Y-m-d H:i:s'); 38 | $data['sign'] = $this->sign($data); 39 | $requestData = $data; 40 | $url = $this->publicParams->apiDomain; 41 | } 42 | 43 | /** 44 | * 签名 45 | * @param $data 46 | * @return string 47 | */ 48 | public function sign($data) 49 | { 50 | $content = $this->parseSignData($data); 51 | if(empty($this->publicParams->appPrivateKeyFile)) 52 | { 53 | $key = $this->publicParams->appPrivateKey; 54 | $method = 'signPrivate'; 55 | } 56 | else 57 | { 58 | $key = $this->publicParams->appPrivateKeyFile; 59 | $method = 'signPrivateFromFile'; 60 | } 61 | switch($this->publicParams->sign_type) 62 | { 63 | case 'RSA': 64 | $result = \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key); 65 | break; 66 | case 'RSA2': 67 | $result = \Yurun\PaySDK\Lib\Encrypt\RSA2::$method($content, $key); 68 | break; 69 | default: 70 | throw new \Exception('未知的加密方式:' . $this->publicParams->sign_type); 71 | } 72 | return \base64_encode($result); 73 | } 74 | 75 | /** 76 | * 验证回调通知是否合法 77 | * @param $data 78 | * @return bool 79 | */ 80 | public function verifyCallback($data) 81 | { 82 | if(!isset($data['sign'], $data['sign_type'])) 83 | { 84 | return false; 85 | } 86 | $signType = $data['sign_type']; 87 | unset($data['sign_type']); 88 | $content = $this->parseSignData($data); 89 | if(empty($this->publicParams->appPublicKeyFile)) 90 | { 91 | $key = $this->publicParams->appPublicKey; 92 | $method = 'verifyPublic'; 93 | } 94 | else 95 | { 96 | $key = $this->publicParams->appPublicKeyFile; 97 | $method = 'verifyPublicFromFile'; 98 | } 99 | switch($signType) 100 | { 101 | case 'RSA': 102 | return \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key, \base64_decode($data['sign'])); 103 | case 'RSA2': 104 | return \Yurun\PaySDK\Lib\Encrypt\RSA2::$method($content, $key, \base64_decode($data['sign'])); 105 | default: 106 | throw new \Exception('未知的加密方式:' . $signType); 107 | } 108 | } 109 | 110 | /** 111 | * 验证同步返回内容 112 | * @param AlipayRequestBase $params 113 | * @param array $data 114 | * @return bool 115 | */ 116 | public function verifySync($params, $data) 117 | { 118 | if(!isset($data['sign'])) 119 | { 120 | return true; 121 | } 122 | $content = \json_encode($data[$params->_syncResponseName], JSON_UNESCAPED_UNICODE); 123 | if(empty($this->publicParams->appPublicKeyFile)) 124 | { 125 | $key = $this->publicParams->appPublicKey; 126 | $method = 'verifyPublic'; 127 | } 128 | else 129 | { 130 | $key = $this->publicParams->appPublicKeyFile; 131 | $method = 'verifyPublicFromFile'; 132 | } 133 | switch($this->publicParams->sign_type) 134 | { 135 | case 'RSA': 136 | return \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key, \base64_decode($data['sign'])); 137 | case 'RSA2': 138 | return \Yurun\PaySDK\Lib\Encrypt\RSA2::$method($content, $key, \base64_decode($data['sign'])); 139 | default: 140 | throw new \Exception('未知的加密方式:' . $this->publicParams->sign_type); 141 | } 142 | } 143 | 144 | public function parseSignData($data) 145 | { 146 | unset($data['sign']); 147 | \ksort($data); 148 | $content = ''; 149 | foreach ($data as $k => $v){ 150 | if($v !== '' && $v !== null && !is_array($v)){ 151 | $content .= $k . '=' . $v . '&'; 152 | } 153 | } 154 | return trim($content, '&'); 155 | } 156 | 157 | /** 158 | * 调用执行接口 159 | * @param mixed $params 160 | * @param string $method 161 | * @return mixed 162 | */ 163 | public function execute($params, $format = 'JSON') 164 | { 165 | $result = parent::execute($params, $format); 166 | if($this->publicParams->isUseAES && isset($result[$params->_syncResponseName])) 167 | { 168 | $result[$params->_syncResponseName] = json_decode(AES::decrypt($result[$params->_syncResponseName], \base64_decode($this->publicParams->aesKey)), true); 169 | } 170 | return $result; 171 | } 172 | 173 | /** 174 | * 检查是否执行成功 175 | * @param array $result 176 | * @return boolean 177 | */ 178 | protected function __checkResult($result) 179 | { 180 | $result = reset($result); 181 | return isset($result['code']) && 10000 == $result['code'] && !isset($result['sub_code']); 182 | } 183 | 184 | /** 185 | * 获取错误信息 186 | * @param array $result 187 | * @return string 188 | */ 189 | protected function __getError($result) 190 | { 191 | $result = reset($result); 192 | if(isset($result['sub_code'])) 193 | { 194 | return $result['sub_msg']; 195 | } 196 | if(isset($result['code']) && 10000 != $result['code']) 197 | { 198 | return $result['msg']; 199 | } 200 | return ''; 201 | } 202 | 203 | /** 204 | * 获取错误代码 205 | * @param array $result 206 | * @return string 207 | */ 208 | protected function __getErrorCode($result) 209 | { 210 | $result = reset($result); 211 | if(isset($result['sub_code'])) 212 | { 213 | return $result['sub_code']; 214 | } 215 | if(isset($result['code']) && 10000 != $result['code']) 216 | { 217 | return $result['code']; 218 | } 219 | return ''; 220 | } 221 | } -------------------------------------------------------------------------------- /src/AlipayCrossBorder/SDK.php: -------------------------------------------------------------------------------- 1 | publicParams), ObjectToArray::parse($params)); 29 | unset($data['apiDomain'], $data['appID'], $data['appPrivateKey'], $data['appPrivateKeyFile'], $data['md5Key'], $data['appPublicKey'], $data['appPublicKeyFile'], $data['_syncResponseName'], $data['_method'], $data['_isSyncVerify']); 30 | $data['partner'] = $this->publicParams->appID; 31 | foreach($data as $key => $value) 32 | { 33 | if('' == $value) 34 | { 35 | unset($data[$key]); 36 | } 37 | } 38 | $data['sign'] = $this->sign($data); 39 | $requestData = $data; 40 | $url = $this->publicParams->apiDomain; 41 | } 42 | 43 | public function sign($data) 44 | { 45 | $content = $this->parseSignData($data); 46 | if(empty($this->publicParams->appPrivateKeyFile)) 47 | { 48 | $key = $this->publicParams->appPrivateKey; 49 | $method = 'signPrivate'; 50 | } 51 | else 52 | { 53 | $key = $this->publicParams->appPrivateKeyFile; 54 | $method = 'signPrivateFromFile'; 55 | } 56 | switch($this->publicParams->sign_type) 57 | { 58 | case 'DSA': 59 | $result = \Yurun\PaySDK\Lib\Encrypt\DSA::$method($content, $key); 60 | break; 61 | case 'RSA': 62 | $result = \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key); 63 | break; 64 | case 'RSA2': 65 | $result = \Yurun\PaySDK\Lib\Encrypt\RSA2::$method($content, $key); 66 | break; 67 | case 'MD5': 68 | return md5($content . $this->publicParams->md5Key); 69 | default: 70 | throw new \Exception('未知的加密方式:' . $this->publicParams->sign_type); 71 | } 72 | return \base64_encode($result); 73 | } 74 | 75 | /** 76 | * 验证回调通知是否合法 77 | * @param $data 78 | * @return bool 79 | */ 80 | public function verifyCallback($data) 81 | { 82 | if(!isset($data['sign'], $data['sign_type'])) 83 | { 84 | return false; 85 | } 86 | $content = $this->parseSignData($data); 87 | if(empty($this->publicParams->appPublicKeyFile)) 88 | { 89 | $key = $this->publicParams->appPublicKey; 90 | $method = 'verifyPublic'; 91 | } 92 | else 93 | { 94 | $key = $this->publicParams->appPublicKeyFile; 95 | $method = 'verifyPublicFromFile'; 96 | } 97 | switch($data['sign_type']) 98 | { 99 | case 'DSA': 100 | return \Yurun\PaySDK\Lib\Encrypt\DSA::$method($content, $key, \base64_decode($data['sign'])); 101 | case 'RSA': 102 | return \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key, \base64_decode($data['sign'])); 103 | case 'MD5': 104 | return $data['sign'] === md5($content . $this->publicParams->md5Key); 105 | default: 106 | throw new \Exception('未知的加密方式:' . $data['sign_type']); 107 | } 108 | } 109 | 110 | /** 111 | * 验证同步返回内容 112 | * @param AlipayRequestBase $params 113 | * @param array $data 114 | * @return bool 115 | */ 116 | public function verifySync($params, $data) 117 | { 118 | if(!isset($data['sign'], $data['sign_type'], $data['response'])) 119 | { 120 | return true; 121 | } 122 | $response = (array)$data['response']; 123 | $content = $this->parseSignData((array)reset($response)); 124 | if(empty($this->publicParams->appPublicKeyFile)) 125 | { 126 | $key = $this->publicParams->appPublicKey; 127 | $method = 'verifyPublic'; 128 | } 129 | else 130 | { 131 | $key = $this->publicParams->appPublicKeyFile; 132 | $method = 'verifyPublicFromFile'; 133 | } 134 | switch($data['sign_type']) 135 | { 136 | case 'DSA': 137 | return \Yurun\PaySDK\Lib\Encrypt\DSA::$method($content, $key, \base64_decode($data['sign'])); 138 | case 'RSA': 139 | return \Yurun\PaySDK\Lib\Encrypt\RSA::$method($content, $key, \base64_decode($data['sign'])); 140 | case 'MD5': 141 | return $data['sign'] === md5($content . $this->publicParams->md5Key); 142 | default: 143 | throw new \Exception('未知的加密方式:' . $data['sign_type']); 144 | } 145 | } 146 | 147 | public function parseSignData($data) 148 | { 149 | unset($data['sign_type'], $data['sign']); 150 | \ksort($data); 151 | $content = ''; 152 | foreach ($data as $k => $v){ 153 | if($v !== '' && $v !== null && !is_array($v)){ 154 | $content .= $k . '=' . $v . '&'; 155 | } 156 | } 157 | return trim($content, '&'); 158 | } 159 | 160 | /** 161 | * 调用执行接口 162 | * @param mixed $params 163 | * @param string $method 164 | * @return mixed 165 | */ 166 | public function execute($params, $format = 'XML') 167 | { 168 | return parent::execute($params, $format); 169 | } 170 | 171 | /** 172 | * 检查是否执行成功 173 | * @param array $result 174 | * @return boolean 175 | */ 176 | protected function __checkResult($result) 177 | { 178 | if(isset($result['is_success']) && 'T' === $result['is_success']) 179 | { 180 | if(isset($result['response'])) 181 | { 182 | $response = (array)$result['response']; 183 | $item = reset($response); 184 | return !isset($item->result_code) || 'SUCCESS' === (string)$item->result_code; 185 | } 186 | else 187 | { 188 | return true; 189 | } 190 | } 191 | return false; 192 | } 193 | 194 | /** 195 | * 获取错误信息 196 | * @param array $result 197 | * @return string 198 | */ 199 | protected function __getError($result) 200 | { 201 | if(isset($result['is_success'])) 202 | { 203 | if('T' === $result['is_success']) 204 | { 205 | if(isset($result['response'])) 206 | { 207 | $response = (array)$result['response']; 208 | $item = reset($response); 209 | if(isset($item->result_code) && 'SUCCESS' !== (string)$item->result_code) 210 | { 211 | if(isset($item->error)) 212 | { 213 | return (string)$item->error; 214 | } 215 | else 216 | { 217 | return (string)$item->detail_error_des; 218 | } 219 | } 220 | } 221 | } 222 | else 223 | { 224 | return $result['error']; 225 | } 226 | } 227 | return ''; 228 | } 229 | 230 | /** 231 | * 获取错误代码 232 | * @param array $result 233 | * @return string 234 | */ 235 | protected function __getErrorCode($result) 236 | { 237 | if(isset($result['is_success'])) 238 | { 239 | if('T' === $result['is_success']) 240 | { 241 | if(isset($result['response'])) 242 | { 243 | $response = (array)$result['response']; 244 | $item = reset($response); 245 | if(isset($item->result_code) && 'SUCCESS' !== (string)$item->result_code) 246 | { 247 | if(isset($item->result_code)) 248 | { 249 | return (string)$item->result_code; 250 | } 251 | else 252 | { 253 | return (string)$item->detail_error_code; 254 | } 255 | } 256 | } 257 | } 258 | else 259 | { 260 | return $result['error']; 261 | } 262 | } 263 | return ''; 264 | } 265 | } -------------------------------------------------------------------------------- /src/Weixin/SDK.php: -------------------------------------------------------------------------------- 1 | publicParams), ObjectToArray::parse($params)); 44 | // 删除不必要的字段 45 | unset($data['apiDomain'], $data['appID'], $data['businessParams'], $data['_apiMethod'], $data['key'], $data['_method'], $data['_isSyncVerify'], $data['certPath'], $data['keyPath'], $data['needSignType'], $data['allowReport'], $data['reportLevel'], $data['needNonceStr'], $data['signType'], $data['needAppID'], $data['rsaPublicCertFile'], $data['needMchID']); 46 | // 企业付款接口特殊处理 47 | if($params->needAppID) 48 | { 49 | if(isset($params->mch_appid)) 50 | { 51 | if('' === $params->mch_appid) 52 | { 53 | $data['mch_appid'] = $this->publicParams->appID; 54 | } 55 | } 56 | else 57 | { 58 | $data['appid'] = $this->publicParams->appID; 59 | } 60 | } 61 | if(!$params->needMchID) 62 | { 63 | unset($data['mch_id']); 64 | } 65 | if(isset($params->mchid) && '' === $params->mchid) 66 | { 67 | $data['mchid'] = $this->publicParams->mch_id; 68 | unset($data['mch_id']); 69 | } 70 | if(isset($params->partnerid) && '' === $params->partnerid) 71 | { 72 | $data['partnerid'] = $this->publicParams->mch_id; 73 | unset($data['mch_id']); 74 | } 75 | // 部分接口不需要nonce_str字段 76 | if(true === $params->needNonceStr) 77 | { 78 | $data['nonce_str'] = \md5(\uniqid('', true)); 79 | } 80 | else if(is_string($params->needNonceStr)) 81 | { 82 | $data[$params->needNonceStr] = \md5(\uniqid('', true)); 83 | } 84 | // 处理某个接口强制使用某种签名方式 85 | if(null === $params->signType) 86 | { 87 | $this->signType = $this->publicParams->sign_type; 88 | } 89 | else 90 | { 91 | $this->signType = $data['sign_type'] = $params->signType; 92 | } 93 | // 部分接口不需要sign_type字段 94 | if(!$params->needSignType) 95 | { 96 | unset($data['sign_type']); 97 | } 98 | foreach($data as $key => $value) 99 | { 100 | if(\is_object($value) && \method_exists($value, 'toString')) 101 | { 102 | $data[$key] = $value->toString(); 103 | } 104 | } 105 | $data['sign'] = $this->sign($data); 106 | $requestData = $this->parseDataToXML($data); 107 | if(false === strpos($params->_apiMethod, '://')) 108 | { 109 | $url = $this->publicParams->apiDomain . $params->_apiMethod; 110 | } 111 | else 112 | { 113 | $url = $params->_apiMethod; 114 | } 115 | } 116 | 117 | /** 118 | * 把数组处理为xml 119 | * @param array $data 120 | * @return string 121 | */ 122 | public function parseDataToXML($data) 123 | { 124 | return XML::toString($data); 125 | } 126 | 127 | /** 128 | * 签名 129 | * @param $data 130 | * @return string 131 | */ 132 | public function sign($data) 133 | { 134 | $content = $this->parseSignData($data); 135 | $signType = null === $this->signType ? $this->publicParams->sign_type : $this->signType; 136 | switch($signType) 137 | { 138 | case 'HMAC-SHA256': 139 | return strtoupper(hash_hmac('sha256', $content, $this->publicParams->key)); 140 | case 'MD5': 141 | return strtoupper(md5($content)); 142 | default: 143 | throw new \Exception('未知的签名方式:' . $signType); 144 | } 145 | } 146 | 147 | /** 148 | * 验证回调通知是否合法 149 | * @param $data 150 | * @return bool 151 | */ 152 | public function verifyCallback($data) 153 | { 154 | if(is_string($data)) 155 | { 156 | $data = XML::fromString($data); 157 | } 158 | if(!isset($data['return_code']) || 'SUCCESS' !== $data['return_code'] || !isset($data['sign'])) 159 | { 160 | return false; 161 | } 162 | $content = $this->parseSignData($data); 163 | switch($this->publicParams->sign_type) 164 | { 165 | case 'HMAC-SHA256': 166 | return strtoupper(hash_hmac('sha256', $content, $this->publicParams->key)) === $data['sign']; 167 | case 'MD5': 168 | return strtoupper(md5($content)) === $data['sign']; 169 | default: 170 | throw new \Exception('未知的签名方式:' . $this->publicParams->sign_type); 171 | } 172 | } 173 | 174 | /** 175 | * 验证同步返回内容 176 | * @param mixed $params 177 | * @param array $data 178 | * @return bool 179 | */ 180 | public function verifySync($params, $data) 181 | { 182 | return $this->verifyCallback($data); 183 | } 184 | 185 | public function parseSignData($data) 186 | { 187 | unset($data['sign']); 188 | \ksort($data); 189 | $data['key'] = $this->publicParams->key; 190 | $content = ''; 191 | foreach ($data as $k => $v){ 192 | if($v != '' && !is_array($v)){ 193 | $content .= $k . '=' . $v . '&'; 194 | } 195 | } 196 | return trim($content, '&'); 197 | } 198 | 199 | /** 200 | * 调用执行接口 201 | * @param mixed $params 202 | * @param string $method 203 | * @return mixed 204 | */ 205 | public function execute($params, $format = 'XML') 206 | { 207 | if(null !== $this->publicParams->certPath) 208 | { 209 | $this->http->sslCert($this->publicParams->certPath); 210 | } 211 | if(null !== $this->publicParams->keyPath) 212 | { 213 | $this->http->sslKey($this->publicParams->keyPath); 214 | } 215 | parent::execute($params, $format); 216 | if($params->allowReport) 217 | { 218 | $this->report($params); 219 | } 220 | return $this->result; 221 | } 222 | 223 | /** 224 | * 上报 225 | * @param mixed $params 226 | * @return void 227 | */ 228 | public function report($params) 229 | { 230 | switch($this->publicParams->reportLevel) 231 | { 232 | case PublicParams::REPORT_LEVEL_NONE: 233 | return; 234 | case PublicParams::REPORT_LEVEL_ALL: 235 | 236 | break; 237 | case PublicParams::REPORT_LEVEL_ERROR: 238 | if($this->checkResult()) 239 | { 240 | return; 241 | } 242 | else if(empty($this->result)) 243 | { 244 | return; 245 | } 246 | break; 247 | } 248 | if(null === $this->reportSDK) 249 | { 250 | $this->reportSDK = new static($this->publicParams); 251 | } 252 | $request = new Request; 253 | $request->interface_url = $this->url; 254 | $request->execute_time_ = (int)($this->response->totalTime() * 1000); 255 | $request->return_code = isset($this->result['return_code']) ? $this->result['return_code'] : (empty($this->result) ? 'FAIL' : 'SUCCESS'); 256 | $request->return_msg = isset($this->result['return_msg']) ? $this->result['return_msg'] : null; 257 | $request->result_code = isset($this->result['result_code']) ? $this->result['result_code'] : (empty($this->result) ? 'FAIL' : 'SUCCESS'); 258 | $request->err_code = isset($this->result['err_code']) ? $this->result['err_code'] : null; 259 | $request->err_code_des = isset($this->result['err_code_des']) ? $this->result['err_code_des'] : null; 260 | $request->user_ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1'; 261 | $request->time = date('YmdHis'); 262 | if(isset($params->device_info)) 263 | { 264 | $request->device_info = $params->device_info; 265 | } 266 | if(isset($params->out_trade_no)) 267 | { 268 | $request->out_trade_no = $params->out_trade_no; 269 | } 270 | } 271 | 272 | /** 273 | * 检查是否执行成功 274 | * @param array $result 275 | * @return boolean 276 | */ 277 | protected function __checkResult($result) 278 | { 279 | return isset($result['return_code']) && 'SUCCESS' === $result['return_code'] && isset($result['result_code']) && 'SUCCESS' === $result['result_code']; 280 | } 281 | 282 | /** 283 | * 获取错误信息 284 | * @param array $result 285 | * @return string 286 | */ 287 | protected function __getError($result) 288 | { 289 | if(isset($result['result_code']) && 'SUCCESS' !== $result['result_code']) 290 | { 291 | return $result['err_code_des']; 292 | } 293 | if(isset($result['return_code']) && 'SUCCESS' !== $result['return_code']) 294 | { 295 | return $result['return_msg']; 296 | } 297 | return ''; 298 | } 299 | 300 | /** 301 | * 获取错误代码 302 | * @param array $result 303 | * @return string 304 | */ 305 | protected function __getErrorCode($result) 306 | { 307 | if(isset($result['result_code']) && 'SUCCESS' !== $result['result_code']) 308 | { 309 | return $result['err_code']; 310 | } 311 | if(isset($result['return_code']) && 'SUCCESS' !== $result['return_code']) 312 | { 313 | return $result['return_code']; 314 | } 315 | return ''; 316 | } 317 | } --------------------------------------------------------------------------------