├── demo ├── wechat.php ├── cer │ └── alipay.cacert.pem ├── wechat.html ├── wechat.refund.php ├── alipay.redirect.php ├── baifu.redirect.php ├── info.php ├── config.php ├── alipay.notify.php ├── wechat.notify.php ├── wechat.redirect.php ├── index.php ├── js │ └── json_to_table.js ├── alipay.redirect.php.html └── wechat.redirect.php.html ├── README.md ├── .gitignore ├── src └── Omnipay │ ├── Wechat │ ├── Sdk │ │ ├── Notify.php │ │ ├── SDKRuntimeException.php │ │ ├── NativeCall.php │ │ ├── OrderQuery.php │ │ ├── ShortUrl.php │ │ ├── DownloadBill.php │ │ ├── WxpayServer.php │ │ ├── NativeLink.php │ │ ├── RefundQuery.php │ │ ├── WxpayClient.php │ │ ├── Refund.php │ │ ├── UnifiedOrder.php │ │ ├── JsApi.php │ │ └── CommonUtil.php │ └── Message │ │ ├── BaseAbstractResponse.php │ │ ├── WechatPrePurchaseResponse.php │ │ ├── WechatCompletePurchaseResponse.php │ │ ├── WechatRefundResponse.php │ │ ├── BaseAbstractRequest.php │ │ ├── WechatPurchaseRequest.php │ │ ├── WechatPrePurchaseRequest.php │ │ ├── WechatRefundRequest.php │ │ ├── WechatPurchaseResponse.php │ │ └── WechatCompletePurchaseRequest.php │ ├── Alipay │ ├── Message │ │ ├── ExpressCompleteRefundResponse.php │ │ ├── ExpressRefundResponse.php │ │ ├── MobileExpressPurchaseResponse.php │ │ ├── PurchaseResponse.php │ │ ├── WapExpressPurchaseResponse.php │ │ ├── WapExpressAuthorizeResponse.php │ │ ├── ExpressCompletePurchaseResponse.php │ │ ├── ExpressCompleteRefundRequest.php │ │ ├── ExpressRefundRequest.php │ │ ├── BaseAbstractRequest.php │ │ ├── WapExpressPurchaseRequest.php │ │ ├── ExpressPurchaseRequest.php │ │ ├── BasePurchaseRequest.php │ │ ├── SecuredPurchaseRequest.php │ │ ├── WapExpressAuthorizeRequest.php │ │ └── MobileExpressPurchaseRequest.php │ ├── DualGateway.php │ ├── MobileExpressGateway.php │ ├── BankGateway.php │ ├── ExpressGateway.php │ ├── SecuredGateway.php │ ├── WapExpressGateway.php │ └── BaseAbstractGateway.php │ ├── Common │ └── Message │ │ └── CompletePurchaseResponseInterface.php │ ├── Netpay │ ├── Message │ │ ├── NetpayCompletePurchaseResponse.php │ │ ├── NetpayCompletePurchaseRequest.php │ │ ├── NetpayPurchaseResponse.php │ │ ├── BaseAbstractRequest.php │ │ └── NetpayPurchaseRequest.php │ └── ExpressGateway.php │ ├── Baifu │ ├── Message │ │ ├── ExpressCompletePurchaseResponse.php │ │ ├── ExpressPurchaseResponse.php │ │ ├── ExpressPurchaseRequest.php │ │ └── ExpressCompletePurchaseRequest.php │ └── ExpressGateway.php │ ├── Utils │ └── Utils.php │ └── Cmpay │ ├── Message │ ├── ExpressPurchaseResponse.php │ └── ExpressPurchaseRequest.php │ ├── ExpressGateway.php │ └── Utils.php ├── composer.json ├── HOWTO └── HOWTO.html /demo/wechat.php: -------------------------------------------------------------------------------- 1 | 4 | * Date: 15/1/19 5 | * Time: 下午5:23 6 | */ 7 | 8 | namespace Omnipay\Alipay\Message; 9 | 10 | 11 | class ExpressCompleteRefundResponse extends ExpressCompletePurchaseResponse { 12 | 13 | 14 | 15 | } -------------------------------------------------------------------------------- /demo/wechat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 微信安全支付 6 | 7 | 8 |

付款中...

9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/BaseAbstractResponse.php: -------------------------------------------------------------------------------- 1 | 9 | **/ 10 | abstract class BaseAbstractResponse extends AbstractResponse { 11 | 12 | 13 | 14 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/SDKRuntimeException.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | class SDKRuntimeException extends \Exception { 10 | public function errorMessage() 11 | { 12 | return $this->getMessage(); 13 | } 14 | } -------------------------------------------------------------------------------- /src/Omnipay/Common/Message/CompletePurchaseResponseInterface.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | interface CompletePurchaseResponseInterface { 10 | /** 11 | * 返回是否交易成功 12 | * @return bool 13 | */ 14 | public function isTradeStatusOk(); 15 | } 16 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/ExpressRefundResponse.php: -------------------------------------------------------------------------------- 1 | 4 | * Date: 14/12/29 5 | * Time: 下午3:05 6 | */ 7 | 8 | namespace Omnipay\Alipay\Message; 9 | 10 | 11 | class ExpressRefundResponse extends PurchaseResponse{ 12 | 13 | /** 14 | * Is the response successful? 15 | * 16 | * @return boolean 17 | */ 18 | public function isSuccessful() 19 | { 20 | // TODO: Implement isSuccessful() method. 21 | } 22 | 23 | public function isRedirect() 24 | { 25 | return true; 26 | } 27 | 28 | 29 | 30 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/MobileExpressPurchaseResponse.php: -------------------------------------------------------------------------------- 1 | data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codelint/chinapay", 3 | "description": "Omnipay's gateway implement for chinese payment service like (alipay, wechat, netpay)", 4 | "require": { 5 | "php-http/guzzle6-adapter": "2.0.1", 6 | "omnipay/common": "v3.0.*", 7 | "doctrine/cache": "1.3.1" 8 | }, 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "codelint", 13 | "email": "codelint@foxmail.com" 14 | } 15 | ], 16 | "autoload": { 17 | "psr-0": {"Omnipay\\": "src/"}, 18 | "files": [ 19 | "src/Omnipay/Utils/helper.php", 20 | "src/Omnipay/Utils/phpqrcode.php" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Omnipay/Netpay/Message/NetpayCompletePurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class NetpayCompletePurchaseResponse extends AbstractResponse implements CompletePurchaseResponseInterface { 12 | 13 | /** 14 | * 返回是否交易成功 15 | * @return bool 16 | */ 17 | public function isTradeStatusOk() 18 | { 19 | return false; 20 | } 21 | 22 | /** 23 | * Is the response successful? 24 | * 25 | * @return boolean 26 | */ 27 | public function isSuccessful() 28 | { 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/DualGateway.php: -------------------------------------------------------------------------------- 1 | setService($this->service_name); 32 | return $this->createRequest('\Omnipay\Alipay\Message\SecuredPurchaseRequest', $parameters); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/NativeCall.php: -------------------------------------------------------------------------------- 1 | returnParameters["return_code"] == "SUCCESS") 12 | { 13 | $this->returnParameters["appid"] = $this->app_id; //公众账号ID 14 | $this->returnParameters["mch_id"] = $this->mch_id; //商户号 15 | $this->returnParameters["nonce_str"] = $this->createNoncestr(); //随机字符串 16 | $this->returnParameters["sign"] = $this->getSign($this->returnParameters); //签名 17 | } 18 | return $this->arrayToXml($this->returnParameters); 19 | } 20 | 21 | /** 22 | * 获取product_id 23 | */ 24 | function getProductId() 25 | { 26 | $product_id = $this->data["product_id"]; 27 | return $product_id; 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /demo/wechat.refund.php: -------------------------------------------------------------------------------- 1 | $_GET['out_trade_no'], 9 | 'transaction_id' => $_GET['transaction_id'], 10 | 'out_refund_no' => $_GET['out_refund_no'], 11 | 'total_fee' => $_GET['total_fee'], 12 | 'refund_fee' => $_GET['refund_fee'] 13 | ]; 14 | 15 | $data = array_filter($data); 16 | 17 | $gateway = new \Omnipay\Wechat\ExpressGateway(); 18 | 19 | 20 | $gateway->setAppId($config['app_id']); 21 | $gateway->setKey($config['pay_sign_key']); 22 | $gateway->setPartner($config['partner']); 23 | $gateway->setPartnerKey($config['partner_key']); 24 | 25 | $gateway->setCertPath($config['cert_path']); 26 | $gateway->setCertKeyPath($config['cert_key_path']); 27 | $gateway->setPubCertPath($config['pub_cert_path']); 28 | 29 | 30 | $req = $gateway->refund($data); 31 | $res = $req->send(); 32 | 33 | echo json_encode($res->getTransactionReference()); -------------------------------------------------------------------------------- /src/Omnipay/Alipay/MobileExpressGateway.php: -------------------------------------------------------------------------------- 1 | createRequest('\Omnipay\Alipay\Message\MobileExpressPurchaseRequest', $parameters); 30 | } 31 | 32 | public function getPrivateKey() 33 | { 34 | return $this->getParameter('private_key'); 35 | } 36 | 37 | public function setPrivateKey($value) 38 | { 39 | $this->setParameter('private_key', $value); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Omnipay/Baifu/Message/ExpressCompletePurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class ExpressCompletePurchaseResponse extends AbstractResponse implements CompletePurchaseResponseInterface{ 12 | 13 | /** 14 | * 返回是否交易成功 15 | * @return bool 16 | */ 17 | public function isTradeStatusOk() 18 | { 19 | $data = $this->getData(); 20 | return ($data['pay_result'] == 1); 21 | } 22 | 23 | /** 24 | * Is the response successful? 25 | * 26 | * @return boolean 27 | */ 28 | public function isSuccessful() 29 | { 30 | return !empty($this->data); 31 | } 32 | 33 | public function getTransactionReference() 34 | { 35 | return $this->getData(); 36 | } 37 | 38 | 39 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatPrePurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | class WechatPrePurchaseResponse extends BaseAbstractResponse { 10 | 11 | public function isRedirect() 12 | { 13 | return false; 14 | } 15 | 16 | /** 17 | * Is the response successful? 18 | * 19 | * @return boolean 20 | */ 21 | public function isSuccessful() 22 | { 23 | return $this->data['return_code'] == 'SUCCESS' && $this->data['result_code'] == 'SUCCESS'; 24 | } 25 | 26 | public function getTransactionReference() 27 | { 28 | return array_only($this->data, array( 29 | 'prepay_id', 'trade_type', 'code_url', 30 | 'appid', 'mch_id', 'device_info', 'nonce_str', 31 | 'sign', 32 | 'result_code', 'err_code', 'err_code_des', 'return_code', 'return_msg' 33 | )); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Omnipay/Netpay/Message/NetpayCompletePurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class NetpayCompletePurchaseRequest extends AbstractRequest { 12 | 13 | /** 14 | * Get the raw data array for this message. The format of this varies from gateway to 15 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 16 | * 17 | * @return mixed 18 | */ 19 | public function getData() 20 | { 21 | // TODO: Implement getData() method. 22 | } 23 | 24 | /** 25 | * Send the request with specified data 26 | * 27 | * @param mixed $data The data to send 28 | * @return ResponseInterface 29 | */ 30 | public function sendData($data) 31 | { 32 | // TODO: Implement sendData() method. 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/PurchaseResponse.php: -------------------------------------------------------------------------------- 1 | getRedirectMethod() == 'GET') { 27 | return $this->getRequest()->getEndpoint() . '?' . http_build_query($this->getRedirectData()); 28 | } else { 29 | return $this->getRequest()->getEndpoint(); 30 | } 31 | } 32 | 33 | public function getRedirectMethod() 34 | { 35 | return 'GET'; 36 | } 37 | 38 | public function getRedirectData() 39 | { 40 | return $this->data; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/WapExpressPurchaseResponse.php: -------------------------------------------------------------------------------- 1 | getRedirectMethod() == 'GET') { 29 | return $this->getRequest()->getEndpoint() . '?' . http_build_query($this->getRedirectData()); 30 | } else { 31 | return $this->getRequest()->getEndpoint(); 32 | } 33 | } 34 | 35 | public function getRedirectMethod() 36 | { 37 | return 'GET'; 38 | } 39 | 40 | public function getRedirectData() 41 | { 42 | return $this->data; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/BankGateway.php: -------------------------------------------------------------------------------- 1 | setService($this->service_name); 34 | $this->setParameter('paymethod', 'bankPay'); 35 | if ($this->getParameter('defaultbank') === null) { 36 | throw new InvalidRequestException("The setDefaultBank(x) method is not called."); 37 | } 38 | return $this->createRequest('\Omnipay\Alipay\Message\ExpressPurchaseRequest', $parameters); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatCompletePurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class WechatCompletePurchaseResponse extends BaseAbstractResponse implements CompletePurchaseResponseInterface { 12 | 13 | /** 14 | * Is the response successful? 15 | * 16 | * @return boolean 17 | */ 18 | public function isSuccessful() 19 | { 20 | return $this->data['status']; 21 | } 22 | 23 | /** 24 | * Does the response require a redirect? 25 | * 26 | * @return boolean 27 | */ 28 | public function isRedirect() 29 | { 30 | return false; 31 | } 32 | 33 | /** 34 | * 返回是否交易成功 35 | * @return bool 36 | */ 37 | public function isTradeStatusOk() 38 | { 39 | return $this->data['trade_status_ok']; 40 | } 41 | 42 | public function getMessage() 43 | { 44 | return $this->data['return_msg']; 45 | } 46 | 47 | 48 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/WapExpressAuthorizeResponse.php: -------------------------------------------------------------------------------- 1 | request = $request; 19 | $this->data = $data; 20 | } 21 | 22 | /** 23 | * Is the response successful? 24 | * 25 | * @return boolean 26 | */ 27 | public function isSuccessful() 28 | { 29 | if (isset($this->data['request_token']) && $this->data['request_token']) { 30 | return true; 31 | } else { 32 | return false; 33 | } 34 | } 35 | 36 | public function getToken() 37 | { 38 | if ($this->isSuccessful()) { 39 | return $this->data['request_token']; 40 | } else { 41 | return ''; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/ExpressCompletePurchaseResponse.php: -------------------------------------------------------------------------------- 1 | data['verify_success']) { 28 | return true; 29 | } else { 30 | return false; 31 | } 32 | } 33 | 34 | public function isTradeStatusOk() 35 | { 36 | $status = $this->request->getTradeStatus(); 37 | return ($status == 'TRADE_FINISHED' || $status == 'TRADE_SUCCESS'); 38 | } 39 | 40 | public function getResponseText() 41 | { 42 | if ($this->isSuccessful()) { 43 | return 'success'; 44 | } else { 45 | return 'fail'; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Omnipay/Netpay/Message/NetpayPurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class NetpayPurchaseResponse extends AbstractResponse implements RedirectResponseInterface{ 12 | 13 | public function isRedirect(){ 14 | return true; 15 | } 16 | 17 | /** 18 | * Gets the redirect target url. 19 | */ 20 | public function getRedirectUrl() 21 | { 22 | return $this->getRequest()->getEndPoint(); 23 | } 24 | 25 | /** 26 | * Get the required redirect method (either GET or POST). 27 | */ 28 | public function getRedirectMethod() 29 | { 30 | return 'POST'; 31 | } 32 | 33 | /** 34 | * Gets the redirect form data array, if the redirect method is POST. 35 | */ 36 | public function getRedirectData() 37 | { 38 | return $this->getData(); 39 | } 40 | 41 | /** 42 | * Is the response successful? 43 | * 44 | * @return boolean 45 | */ 46 | public function isSuccessful() 47 | { 48 | return false; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/OrderQuery.php: -------------------------------------------------------------------------------- 1 | url = "https://api.mch.weixin.qq.com/pay/orderquery"; 11 | //设置curl超时时间 12 | $this->curl_timeout = static::CURL_TIMEOUT; 13 | } 14 | 15 | /** 16 | * 生成接口参数xml 17 | */ 18 | function createXml() 19 | { 20 | try 21 | { 22 | //检测必填参数 23 | if ($this->parameters["out_trade_no"] == null && 24 | $this->parameters["transaction_id"] == null 25 | ) 26 | { 27 | throw new SDKRuntimeException("订单查询接口中,out_trade_no、transaction_id至少填一个!" . "
"); 28 | } 29 | $this->parameters["appid"] = $this->app_id; //公众账号ID 30 | $this->parameters["mch_id"] = $this->mch_id; //商户号 31 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 32 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 33 | return $this->arrayToXml($this->parameters); 34 | } catch (SDKRuntimeException $e) 35 | { 36 | die($e->errorMessage()); 37 | } 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/ExpressGateway.php: -------------------------------------------------------------------------------- 1 | setService($this->service_name); 30 | return $this->createRequest('\Omnipay\Alipay\Message\ExpressPurchaseRequest', $parameters); 31 | } 32 | 33 | /** 34 | * support refund for express pay 35 | * @param array $parameters exp: ['refund_data' => [ [ 'trade_no' => 'alipay trade no', 'total_fee' => 'the fee to refund', 'memo' => ''] ] ] 36 | */ 37 | public function refund(array $parameters = array()) 38 | { 39 | $this->setService($this->refund_service_name); 40 | return $this->createRequest('\Omnipay\Alipay\Message\ExpressRefundRequest', $parameters); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/ShortUrl.php: -------------------------------------------------------------------------------- 1 | url = "https://api.mch.weixin.qq.com/tools/shorturl"; 11 | //设置curl超时时间 12 | $this->curl_timeout = static::CURL_TIMEOUT; 13 | } 14 | 15 | /** 16 | * 生成接口参数xml 17 | */ 18 | function createXml() 19 | { 20 | try 21 | { 22 | if ($this->parameters["long_url"] == null) 23 | { 24 | throw new SDKRuntimeException("短链接转换接口中,缺少必填参数long_url!" . "
"); 25 | } 26 | $this->parameters["appid"] = $this->app_id; //公众账号ID 27 | $this->parameters["mch_id"] = $this->mch_id; //商户号 28 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 29 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 30 | return $this->arrayToXml($this->parameters); 31 | } catch (SDKRuntimeException $e) 32 | { 33 | die($e->errorMessage()); 34 | } 35 | } 36 | 37 | /** 38 | * 获取prepay_id 39 | */ 40 | function getShortUrl() 41 | { 42 | $this->postXml(); 43 | $prepay_id = $this->result["short_url"]; 44 | return $prepay_id; 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/Omnipay/Utils/Utils.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | class Utils { 10 | 11 | static function load_helper() 12 | { 13 | require_once(__DIR__ . '/helper.php'); 14 | } 15 | 16 | /** 17 | * format the wap alipay's notify on the xml value .notify_data 18 | * @param $params ['notify_data' => ''] 19 | * @return array 20 | */ 21 | static function format_wap_alipay_notify($params) 22 | { 23 | // $params = array_merge($get, $post); 24 | if (!empty($params['notify_data'])) 25 | { 26 | $notify_data = $params['notify_data']; 27 | $doc = new \DOMDocument(); 28 | $doc->loadXML($notify_data); 29 | if (!empty($doc->getElementsByTagName("notify")->item(0)->nodeValue)) 30 | { 31 | $fields = array( 32 | 'notify_id', 'subject', 33 | 'out_trade_no', 'trade_no', 'trade_status', 'total_fee', 34 | 'buyer_email', 'buyer_id' 35 | ); 36 | foreach ($fields as $f) 37 | { 38 | $params[$f] = $doc->getElementsByTagName($f)->item(0)->nodeValue; 39 | } 40 | } 41 | } 42 | return $params; 43 | } 44 | 45 | 46 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatRefundResponse.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | class WechatRefundResponse extends BaseAbstractResponse { 10 | 11 | /** 12 | * Is the response successful? 13 | * 14 | * @return boolean 15 | */ 16 | public function isSuccessful() 17 | { 18 | return $this->data['return_code'] == 'SUCCESS' && $this->data['result_code'] == 'SUCCESS'; 19 | } 20 | 21 | public function getTransactionReference() 22 | { 23 | $res = array_only($this->data, array( 24 | 'transaction_id', 'out_trade_no', 'out_refund_no', 25 | 'refund_id', 'refund_fee', 'total_fee', 'cash_fee', 'cash_refund_fee', 26 | 'appid', 'mch_id', 'device_info', 'nonce_str', 27 | 'sign', 28 | 'result_code', 'err_code', 'err_code_des', 'return_code', 'return_msg' 29 | )); 30 | if($this->isSuccessful()){ 31 | $res['total_fee'] = round(abs($res['total_fee'])/100.0, 2); 32 | $res['cash_fee'] = round(abs($res['cash_fee'])/100.0, 2); 33 | $res['cash_refund_fee'] = round(abs($res['cash_refund_fee'])/100.0, 2); 34 | $res['refund_fee'] = round(abs($res['refund_fee'])/100.0, 2); 35 | } 36 | return $res; 37 | } 38 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/DownloadBill.php: -------------------------------------------------------------------------------- 1 | url = "https://api.mch.weixin.qq.com/pay/downloadbill"; 12 | //设置curl超时时间 13 | $this->curl_timeout = static::CURL_TIMEOUT; 14 | } 15 | 16 | /** 17 | * 生成接口参数xml 18 | */ 19 | function createXml() 20 | { 21 | try 22 | { 23 | if ($this->parameters["bill_date"] == null) 24 | { 25 | throw new SDKRuntimeException("对账单接口中,缺少必填参数bill_date!" . "
"); 26 | } 27 | $this->parameters["appid"] = $this->app_id; //公众账号ID 28 | $this->parameters["mch_id"] = $this->mch_id; //商户号 29 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 30 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 31 | return $this->arrayToXml($this->parameters); 32 | } catch (SDKRuntimeException $e) 33 | { 34 | die($e->errorMessage()); 35 | } 36 | } 37 | 38 | /** 39 | * 作用:获取结果,默认不使用证书 40 | */ 41 | function getResult() 42 | { 43 | $this->postXml(); 44 | $this->result = $this->xmlToArray($this->result_xml); 45 | return $this->result; 46 | } 47 | 48 | 49 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/WxpayServer.php: -------------------------------------------------------------------------------- 1 | data = $this->xmlToArray($xml); 16 | } 17 | 18 | function checkSign() 19 | { 20 | $tmpData = $this->data; 21 | unset($tmpData['sign']); 22 | $sign = $this->getSign($tmpData); //本地签名 23 | if ($this->data['sign'] == $sign) 24 | { 25 | return TRUE; 26 | } 27 | return FALSE; 28 | } 29 | 30 | /** 31 | * 获取微信的请求数据 32 | */ 33 | function getData() 34 | { 35 | return $this->data; 36 | } 37 | 38 | /** 39 | * 设置返回微信的xml数据 40 | */ 41 | function setReturnParameter($parameter, $parameterValue) 42 | { 43 | $this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue); 44 | } 45 | 46 | /** 47 | * 生成接口参数xml 48 | */ 49 | function createXml() 50 | { 51 | return $this->arrayToXml($this->returnParameters); 52 | } 53 | 54 | /** 55 | * 将xml数据返回微信 56 | */ 57 | function returnXml() 58 | { 59 | $returnXml = $this->createXml(); 60 | return $returnXml; 61 | } 62 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/ExpressCompleteRefundRequest.php: -------------------------------------------------------------------------------- 1 | 4 | * Date: 15/1/19 5 | * Time: 下午5:22 6 | */ 7 | 8 | namespace Omnipay\Alipay\Message; 9 | 10 | 11 | class ExpressCompleteRefundRequest extends ExpressCompletePurchaseRequest { 12 | 13 | public function getData() 14 | { 15 | $this->validate('request_params', 'transport', 'partner', 'ca_cert_path', 'sign_type', 'key'); 16 | $this->validateRequestParams('result_details', 'batch_no', 'success_num'); 17 | return $this->getParameters(); 18 | } 19 | 20 | public function sendData($data) 21 | { 22 | $notify_id = $this->getNotifyId(); 23 | $sign = $this->getRequestParam('sign'); 24 | $validateSign = !empty($sign); 25 | 26 | $this->verifyResponse = 'true'; 27 | if (!is_null($notify_id)) 28 | { 29 | $this->verifyResponse = $this->getVerifyResponse($this->getNotifyId()); 30 | $validateSign = true; 31 | } 32 | 33 | $data = array(); 34 | $data['verify_response'] = $this->verifyResponse; 35 | if ($this->isResponseOk($this->verifyResponse) && (!$validateSign || $this->isSignMatch())) 36 | { 37 | $data['verify_success'] = true; 38 | } 39 | else 40 | { 41 | $data['verify_success'] = false; 42 | } 43 | return $this->response = new ExpressCompleteRefundResponse($this, $data); 44 | } 45 | } -------------------------------------------------------------------------------- /src/Omnipay/Baifu/Message/ExpressPurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 11 | **/ 12 | class ExpressPurchaseResponse extends AbstractResponse implements RedirectResponseInterface { 13 | 14 | protected $endpoint = 'https://www.baifubao.com/api/0/pay/0/wapdirect/0'; 15 | 16 | private $redirectMethod = 'GET'; 17 | 18 | /** 19 | * Gets the redirect target url. 20 | */ 21 | public function getRedirectUrl() 22 | { 23 | $data = $this->getData(); 24 | return $this->endpoint . '?' . http_build_query($data); 25 | } 26 | 27 | /** 28 | * Get the required redirect method (either GET or POST). 29 | */ 30 | public function getRedirectMethod() 31 | { 32 | $this->redirectMethod; 33 | } 34 | 35 | /** 36 | * Gets the redirect form data array, if the redirect method is POST. 37 | */ 38 | public function getRedirectData() 39 | { 40 | return []; 41 | } 42 | 43 | /** 44 | * Is the response successful? 45 | * 46 | * @return boolean 47 | */ 48 | public function isSuccessful() 49 | { 50 | return true; 51 | } 52 | 53 | public function isRedirect() 54 | { 55 | return true; 56 | } 57 | 58 | 59 | public function redirect() 60 | { 61 | Header('Location: ' . $this->getRedirectUrl()); 62 | } 63 | 64 | 65 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/NativeLink.php: -------------------------------------------------------------------------------- 1 | parameters[$this->trimString($parameter)] = $this->trimString($parameterValue); 20 | } 21 | 22 | /** 23 | * 生成Native支付链接二维码 24 | */ 25 | function createLink() 26 | { 27 | try 28 | { 29 | if ($this->parameters["product_id"] == null) 30 | { 31 | throw new SDKRuntimeException("缺少Native支付二维码链接必填参数product_id!" . "
"); 32 | } 33 | $this->parameters["appid"] = $this->app_id; //公众账号ID 34 | $this->parameters["mch_id"] = $this->mch_id; //商户号 35 | $time_stamp = time(); 36 | $this->parameters["time_stamp"] = "$time_stamp"; //时间戳 37 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 38 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 39 | $bizString = $this->formatBizQueryParaMap($this->parameters, false); 40 | $this->url = "weixin://wxpay/bizpayurl?" . $bizString; 41 | } catch (SDKRuntimeException $e) 42 | { 43 | die($e->errorMessage()); 44 | } 45 | } 46 | 47 | /** 48 | * 返回链接 49 | */ 50 | function getUrl() 51 | { 52 | $this->createLink(); 53 | return $this->url; 54 | } 55 | } -------------------------------------------------------------------------------- /demo/alipay.redirect.php: -------------------------------------------------------------------------------- 1 | setPartner($config['partner']); 20 | $gateway->setKey($config['key']); 21 | $gateway->setSellerEmail($config['seller_email']); 22 | $gateway->setNotifyUrl($config['notify_url']); 23 | $gateway->setReturnUrl($config['return_url']); 24 | $gateway->setCancelUrl($config['cancel_url']); 25 | $opts = array( 26 | 'subject' => $_GET['subject'], 27 | 'description' => '暂无', 28 | 'total_fee' => $_GET['total_fee'], 29 | 'out_trade_no' => $_GET['out_trade_no'], 30 | ); 31 | $res = $gateway->purchase($opts)->send(); 32 | $cache = get_cache(); 33 | $cache->save($_GET['out_trade_no'], $opts); 34 | $res->redirect(); 35 | // header("Content-type: application/json"); 36 | // echo json_encode([ 37 | // 'url' => $res->getRedirectUrl(), 38 | // 'opts' => $opts, 39 | // 'config' => $config, 40 | // 'info_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/demo/info.php?out_trade_no=' . $out_trade_no, 41 | // ]); 42 | } catch (\Exception $e) 43 | { 44 | var_dump($e->getMessage()); 45 | } 46 | } 47 | 48 | alipay_redirect($config); -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/RefundQuery.php: -------------------------------------------------------------------------------- 1 | url = "https://api.mch.weixin.qq.com/pay/refundquery"; 12 | //设置curl超时时间 13 | $this->curl_timeout = static::CURL_TIMEOUT; 14 | } 15 | 16 | /** 17 | * 生成接口参数xml 18 | */ 19 | function createXml() 20 | { 21 | try 22 | { 23 | if ($this->parameters["out_refund_no"] == null && 24 | $this->parameters["out_trade_no"] == null && 25 | $this->parameters["transaction_id"] == null && 26 | $this->parameters["refund_id "] == null 27 | ) 28 | { 29 | throw new SDKRuntimeException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!" . "
"); 30 | } 31 | $this->parameters["appid"] = $this->app_id; //公众账号ID 32 | $this->parameters["mch_id"] = $this->mch_id; //商户号 33 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 34 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 35 | return $this->arrayToXml($this->parameters); 36 | } catch (SDKRuntimeException $e) 37 | { 38 | die($e->errorMessage()); 39 | } 40 | } 41 | 42 | /** 43 | * 作用:获取结果,使用证书通信 44 | */ 45 | function getResult() 46 | { 47 | $this->postXmlSSL(); 48 | $this->result = $this->xmlToArray($this->response); 49 | return $this->result; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/WxpayClient.php: -------------------------------------------------------------------------------- 1 | parameters[$this->trimString($parameter)] = $this->trimString($parameterValue); 19 | } 20 | 21 | /** 22 | * 作用:设置标配的请求参数,生成签名,生成接口参数xml 23 | */ 24 | function createXml() 25 | { 26 | $this->parameters["appid"] = $this->app_id; //公众账号ID 27 | $this->parameters["mch_id"] = $this->mch_id; //商户号 28 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 29 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 30 | return $this->arrayToXml($this->parameters); 31 | } 32 | 33 | /** 34 | * 作用:post请求xml 35 | */ 36 | function postXml() 37 | { 38 | $xml = $this->createXml(); 39 | $this->response = $this->postXmlCurl($xml, $this->url, $this->curl_timeout); 40 | return $this->response; 41 | } 42 | 43 | /** 44 | * 作用:使用证书post请求xml 45 | */ 46 | function postXmlSSL() 47 | { 48 | $xml = $this->createXml(); 49 | $this->response = $this->postXmlSSLCurl($xml, $this->url, $this->curl_timeout); 50 | return $this->response; 51 | } 52 | 53 | /** 54 | * 作用:获取结果,默认不使用证书 55 | */ 56 | function getResult() 57 | { 58 | $this->postXml(); 59 | $this->result = $this->xmlToArray($this->response); 60 | return $this->result; 61 | } 62 | } -------------------------------------------------------------------------------- /demo/baifu.redirect.php: -------------------------------------------------------------------------------- 1 | setPartner($config['partner']); 20 | $gateway->setKey($config['key']); 21 | $gateway->setNotifyUrl($config['notify_url']); 22 | $gateway->setReturnUrl($config['return_url']); 23 | $gateway->setCertPath($config['cert_path']); 24 | $opts = array( 25 | 'sp_pass_through' => '%7B%22offline_pay%22%3A1%7D', 26 | 'subject' => $_GET['subject'], 27 | 'description' => '暂无', 28 | 'total_fee' => $_GET['total_fee'], 29 | 'out_trade_no' => $_GET['out_trade_no'], 30 | ); 31 | $res = $gateway->purchase($opts)->send(); 32 | // $res = $gateway->completePurchase($opts)->send(); 33 | // $abc = [ 'result' => $res->getTransactionReference(), 'trade_status' => $res->isTradeStatusOk()]; 34 | // var_dump($abc); 35 | $cache = get_cache(); 36 | $cache->save($_GET['out_trade_no'], $opts); 37 | $res->redirect(); 38 | // header("Content-type: application/json"); 39 | // echo json_encode([ 40 | // 'url' => $res->getRedirectUrl(), 41 | // 'opts' => $opts, 42 | // 'config' => $config, 43 | // 'info_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/demo/info.php?out_trade_no=' . $out_trade_no, 44 | // ]); 45 | } catch (\Exception $e) 46 | { 47 | var_dump($e->getMessage()); 48 | } 49 | } 50 | 51 | alipay_redirect($config); -------------------------------------------------------------------------------- /HOWTO: -------------------------------------------------------------------------------- 1 | Demo Entry 演示入口 2 | 3 | demo/index.php : 为demo的入口地址,可以测试支付宝支付,微信支付需要填入相关配置,支付宝配置已经填入 4 | 5 | demo/config.php : 包含了一些通用配置,例如加载库,所需要库在vendor目录里,通过文件中: 6 | require_once('../vendor/autoload.php'); 语句加载 7 | 8 | -------------------------------------------------------------------------------- 9 | Modify Alipay/Wechat Config 修改配置 10 | 11 | 修改文件demo/config.php的返回值可修改配置 12 | 13 | -------------------------------------------------------------------------------- 14 | 15 | About alipay.wap use: 16 | 17 | demo/alipay.redirect.php : the demo for redirect use 关于如何跳转到支付界面的代码演示 18 | 19 | demo/alipay.notify.php : the demo for notify use 关于如何响应通知的演示 20 | 21 | the return url have the same params as alipay server post to demo/alipay.notify.php when 22 | the return url call. 23 | 当用户支付完成后,返回到return_url指定的路径时,所含参数阿里服务器通知支付结果到alipay.notify.php时, 24 | POST的参数一致。 25 | 微信使用: 26 | $_GET['out_trade_no']: 为订单号, 27 | $_GET['trade_no']: 为流水号, 28 | $_GET['total_fee']为订单金额 29 | 30 | ---------------------------------------------------------------------------------- 31 | 32 | About WeChat: 33 | 34 | demo/wechat.redirect.php 35 | show how to redirect to pay by Wechat 支付跳转演示 36 | 注意:这里输入的金额单位以元(接口做了处理,使得网关跳转接口一致使用元作为单位,但微信实际使用“分” 37 | 做单位,因此在响应接口中,微信返回的金额单位为:“分”,不是元) 38 | 39 | demo/wechat.notify.php 40 | show how to react the payment result notify. 响应支付结果 41 | 42 | About return_url: 43 | 支付完成跳转回来,微信使用POST,其参数与[demo/wechat.notify.php]一致。 44 | 微信使用: 45 | $_GET['out_trade_no'] 订单号, 46 | $_GET['bank_billno'] 流水号, 47 | $_GET['product_fee'] 订单金额(单位为分, 注意这里单位与跳转的时候使用的不一致) 48 | 通知/返回 url的其他参数: 49 | $_GET['notify_id'] 消息id 50 | $_GET['transaction_id'] 交易号 51 | 52 | --------------------------------------------------------------------------------- 53 | 通过demo/info.php?out_trade_no=xxxxxxxxxx可以查看支付状态, 返回为一个JSON, 里面记录了 54 | 指定订单号(out_trade_no)的支付情况(跳转时使用的参数) 55 | last_notify: 上一次支付通知的记录(包括通知的url,以及$_GET, $_POST内容) 56 | last_error: 上一次支付通知失败纪录 57 | 58 | -------------------------------------------------------------------------------- /demo/info.php: -------------------------------------------------------------------------------- 1 | $cache->fetch($out_trade_no), 11 | 'last_notify' => $cache->fetch(LAST_NOTIFY_CACHE_KEY), 12 | 'last_error' => $cache->fetch(LAST_ERROR_CACHE_KEY) 13 | ); 14 | $serial = $cache->fetch($out_trade_no); 15 | $serial['trade_no'] = $out_trade_no; 16 | $last_notify = $cache->fetch(LAST_NOTIFY_CACHE_KEY); 17 | $last_error = $cache->fetch(LAST_ERROR_CACHE_KEY); 18 | // echo(json_encode($data)); 19 | ?> 20 | 22 | 23 | 24 | 25 | <?php echo $_GET['out_trade_no'] ?> 26 | 27 | 28 | 29 | 30 |
31 | 35 |
36 | 37 | 38 | 39 | 52 | 53 | -------------------------------------------------------------------------------- /src/Omnipay/Baifu/ExpressGateway.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class ExpressGateway extends AbstractGateway { 12 | 13 | /** 14 | * Get gateway display name 15 | * 16 | * This can be used by carts to get the display name for each gateway. 17 | */ 18 | public function getName() 19 | { 20 | return 'Baifu_Express'; 21 | } 22 | 23 | function setKey($filepath) 24 | { 25 | $this->setParameter('key', $filepath); 26 | } 27 | 28 | function getKey() 29 | { 30 | return $this->getParameter('key'); 31 | } 32 | 33 | function getPartner() 34 | { 35 | return $this->getParameter('partner_id'); 36 | } 37 | 38 | function setPartner($id) 39 | { 40 | $this->setParameter('partner_id', $id); 41 | } 42 | 43 | function getNotifyUrl() 44 | { 45 | return $this->getParameter('notify_url'); 46 | } 47 | 48 | function setNotifyUrl($url) 49 | { 50 | $this->setParameter('notify_url', $url); 51 | } 52 | 53 | function setReturnUrl($url) 54 | { 55 | $this->setParameter('return_url', $url); 56 | } 57 | 58 | function getReturnUrl() 59 | { 60 | return $this->getParameter('return_url'); 61 | } 62 | 63 | function setCertPath($cert) 64 | { 65 | $this->setParameter('cert_path', $cert); 66 | } 67 | 68 | function getCertPath() 69 | { 70 | $this->getParameter('cert_path'); 71 | } 72 | 73 | 74 | public function purchase(array $parameters = []) 75 | { 76 | return $this->createRequest('\Omnipay\Baifu\Message\ExpressPurchaseRequest', $parameters); 77 | } 78 | 79 | /** 80 | * @param array $parameters 81 | * @return \Omnipay\Baifu\Message\ExpressCompletePurchaseRequest 82 | */ 83 | public function completePurchase(array $parameters = array()) 84 | { 85 | return $this->createRequest('\Omnipay\Baifu\Message\ExpressCompletePurchaseRequest', $parameters); 86 | } 87 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/Refund.php: -------------------------------------------------------------------------------- 1 | url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; 12 | //设置curl超时时间 13 | $this->curl_timeout = static::CURL_TIMEOUT; 14 | } 15 | 16 | /** 17 | * 生成接口参数xml 18 | */ 19 | function createXml() 20 | { 21 | try 22 | { 23 | //检测必填参数 24 | if ($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) 25 | { 26 | throw new SDKRuntimeException("退款申请接口中,out_trade_no、transaction_id至少填一个!" . "
"); 27 | } 28 | elseif ($this->parameters["out_refund_no"] == null) 29 | { 30 | throw new SDKRuntimeException("退款申请接口中,缺少必填参数out_refund_no!" . "
"); 31 | } 32 | elseif ($this->parameters["total_fee"] == null) 33 | { 34 | throw new SDKRuntimeException("退款申请接口中,缺少必填参数total_fee!" . "
"); 35 | } 36 | elseif ($this->parameters["refund_fee"] == null) 37 | { 38 | throw new SDKRuntimeException("退款申请接口中,缺少必填参数refund_fee!" . "
"); 39 | } 40 | elseif ($this->parameters["op_user_id"] == null) 41 | { 42 | throw new SDKRuntimeException("退款申请接口中,缺少必填参数op_user_id!" . "
"); 43 | } 44 | $this->parameters["appid"] = $this->app_id; //公众账号ID 45 | $this->parameters["mch_id"] = $this->mch_id; //商户号 46 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 47 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 48 | return $this->arrayToXml($this->parameters); 49 | } catch (SDKRuntimeException $e) 50 | { 51 | die($e->errorMessage()); 52 | } 53 | } 54 | 55 | /** 56 | * 作用:获取结果,使用证书通信 57 | */ 58 | function getResult() 59 | { 60 | $this->postXmlSSL(); 61 | $this->result = $this->xmlToArray($this->response); 62 | return $this->result; 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/Omnipay/Netpay/Message/BaseAbstractRequest.php: -------------------------------------------------------------------------------- 1 | 9 | **/ 10 | abstract class BaseAbstractRequest extends AbstractRequest { 11 | private $keyFile = ''; 12 | private $certFile = ''; 13 | 14 | function setKeyFile($filepath) 15 | { 16 | $this->keyFile = $filepath; 17 | } 18 | 19 | function getKeyFile() 20 | { 21 | return $this->keyFile; 22 | } 23 | 24 | function setCertFile($filepath) 25 | { 26 | $this->certFile = $filepath; 27 | } 28 | 29 | function getCertFile() 30 | { 31 | return $this->certFile; 32 | } 33 | 34 | function getPartner() 35 | { 36 | return $this->getParameter('partner'); 37 | } 38 | 39 | function setPartner($id) 40 | { 41 | $this->setParameter('partner', $id); 42 | } 43 | 44 | public function getTotalFee() 45 | { 46 | return $this->getParameter('total_fee'); 47 | } 48 | 49 | public function setTotalFee($value) 50 | { 51 | $this->setParameter('total_fee', $value); 52 | } 53 | 54 | function getCurrency() 55 | { 56 | return $this->getParameter('currency') ? : 'CNY'; 57 | } 58 | 59 | public function getOutTradeNo() 60 | { 61 | return $this->getParameter('out_trade_no'); 62 | } 63 | 64 | public function setOutTradeNo($value) 65 | { 66 | $this->setParameter('out_trade_no', $value); 67 | } 68 | 69 | function getBankCode() 70 | { 71 | return $this->getParameter('bank') ? : ''; 72 | } 73 | 74 | function setBankCode($bc) 75 | { 76 | $this->setParameter('bank', $bc); 77 | } 78 | 79 | function getResultMode() 80 | { 81 | return $this->getParameter('result_mode') ? : '0'; 82 | } 83 | 84 | function setResultMode($mode) 85 | { 86 | $this->setParameter('result_mode', $mode); 87 | } 88 | 89 | function getDescription(){ 90 | return $this->getParameter('description') ? : ''; 91 | } 92 | 93 | function setDescription($desc){ 94 | $this->setParameter('description', $desc); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /demo/config.php: -------------------------------------------------------------------------------- 1 | save('test.it.ok_or_not', true); 30 | return $cache; 31 | } catch (\Exception $e) 32 | { 33 | return new \Doctrine\Common\Cache\ArrayCache(); 34 | } 35 | } 36 | 37 | return array( 38 | 'alipay' => array( 39 | 'partner' => '*', 40 | 'key' => '*', 41 | 'seller_email' => '*', //just need by alipay gateway 42 | 'return_url' => base_url('/index.php'), 43 | 'notify_url' => base_url('/alipay.notify.php'), 44 | 'cancel_url' => base_url('/index.php'), 45 | 'ca_cert_path' => __DIR__ . '/cer/alipay.cacert.pem' 46 | ), 47 | 'wechat' => array( 48 | 'app_id' => '*', 49 | 'app_secret' => '*', 50 | 'pay_sign_key' => '*', 51 | 'partner' => '*', 52 | 'partner_key' => '*', 53 | 54 | 'cert_path' => '/home/dev/app/jenkins/data/workspace/www/cer/wechat/apiclient_cert.pem', 55 | 'cert_key_path' => '/home/dev/app/jenkins/data/workspace/www/cer/wechat/apiclient_key.pem', 56 | 'pub_cert_path' => '/home/dev/app/jenkins/data/workspace/www/cer/wechat/rootca.pem' 57 | 58 | 'return_url' => base_url('/index.php'), 59 | 'notify_url' => base_url('/wechat.notify.php'), 60 | 'cancel_url' => base_url('/index.php'), 61 | ), 62 | 63 | 'baifu' => array( 64 | 'partner' => '*', 65 | 'key' => '*', 66 | 'return_url' => base_url('/index.php'), 67 | 'notify_url' => base_url('/baifu.notify.php'), 68 | 'cancel_url' => base_url('/index.php'), 69 | ) 70 | ); 71 | -------------------------------------------------------------------------------- /src/Omnipay/Netpay/Message/NetpayPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class NetpayPurchaseRequest extends BaseAbstractRequest { 12 | 13 | protected $endpoint = 'https://www.gnete.com/bin/scripts/OpenVendor/gnete/V34/GetOvOrder.asp'; 14 | // protected $endpoint = 'http://test.gnete.com:8888/Bin/Scripts/OpenVendor/Gnete/V34/GetOvOrder.asp'; 15 | 16 | function getEndPoint() 17 | { 18 | return $this->endpoint; 19 | } 20 | 21 | function setEndPoint($endpoint) 22 | { 23 | $this->endpoint = $endpoint; 24 | } 25 | 26 | /** 27 | * Get the raw data array for this message. The format of this varies from gateway to 28 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 29 | * 30 | * @return mixed 31 | */ 32 | public function getData() 33 | { 34 | $this->validate( 35 | 'partner', 36 | 'out_trade_no', 37 | 'total_fee', 38 | 'notifyUrl' 39 | ); 40 | 41 | $text = 'MerId=' . $this->getPartner() . '&' . 42 | 'OrderNo=' . $this->getOutTradeNo() . '&' . 43 | 'OrderAmount=' . $this->getTotalFee() . '&' . 44 | 'CurrCode=' . $this->getCurrency() . '&' . 45 | 'CallBackUrl=' . $this->getNotifyUrl() . '&' . 46 | 'BankCode=' . $this->getBankCode() . '&' . 47 | 'ResultMode=' . $this->getResultMode() . '&' . 48 | 'Reserved01=' . $this->getDescription() . '&' . 49 | 'Reserved02='; 50 | $obj = new NetTran(); 51 | 52 | $encodeMsg = $obj->EncryptMsg($text, $this->getCertFile()) ? $obj->getLastResult() : ''; 53 | $signedMsg = $obj->SignMsg($text, $this->getKeyFile(), "12345678") ? $obj->getLastResult() : ''; 54 | return [ 55 | 'EncodeMsg' => $encodeMsg, 56 | 'SignMsg' => $signedMsg 57 | ]; 58 | } 59 | 60 | /** 61 | * Send the request with specified data 62 | * 63 | * @param mixed $data The data to send 64 | * @return ResponseInterface 65 | */ 66 | public function sendData($data) 67 | { 68 | return $this->response = new NetpayPurchaseResponse($this, $data); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/ExpressRefundRequest.php: -------------------------------------------------------------------------------- 1 | 4 | * Date: 14/12/29 5 | * Time: 下午3:04 6 | */ 7 | 8 | namespace Omnipay\Alipay\Message; 9 | 10 | 11 | use Omnipay\Common\Message\ResponseInterface; 12 | 13 | class ExpressRefundRequest extends BasePurchaseRequest { 14 | 15 | protected function validateData() 16 | { 17 | return $this->validate( 18 | 'service', 19 | 'partner', 20 | 'key', 21 | 'seller_email', 22 | 'refund_data', 23 | 'notify_url' 24 | ); 25 | } 26 | 27 | function getRefundData() 28 | { 29 | return $this->parameters->get('refund_data'); 30 | } 31 | 32 | function setRefundData($data) 33 | { 34 | $this->parameters->set('refund_data', $data); 35 | } 36 | 37 | /** 38 | * Get the raw data array for this message. The format of this varies from gateway to 39 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 40 | * 41 | * @return mixed 42 | */ 43 | public function getData() 44 | { 45 | $this->validateData(); 46 | $detail = $this->getRefundData(); 47 | 48 | foreach ($detail as &$v) 49 | { 50 | $v = $v['trade_no'] . '^' . $v['total_fee'] . '^' . $v['memo']; 51 | } 52 | $data = array( 53 | "service" => $this->getService(), 54 | "partner" => $this->getPartner(), 55 | "seller_user_id" => $this->getPartner(), 56 | "refund_date" => date('Y-m-d H:i:s'), 57 | "batch_no" => date('YmdHi') . rand(10000, 99999), 58 | 'batch_num' => count($detail), 59 | 'detail_data' => implode('#', $detail), 60 | "notify_url" => $this->getNotifyUrl(), 61 | "seller_email" => $this->getSellerEmail(), 62 | "_input_charset" => $this->getInputCharset(), 63 | ); 64 | $data = array_filter($data); 65 | $data['sign'] = $this->getParamsSignature($data); 66 | $data['sign_type'] = $this->getSignType(); 67 | return $data; 68 | } 69 | 70 | /** 71 | * Send the request with specified data 72 | * 73 | * @param mixed $data The data to send 74 | * @return ResponseInterface 75 | */ 76 | public function sendData($data) 77 | { 78 | return $this->response = new ExpressRefundResponse($this, $data); 79 | } 80 | } -------------------------------------------------------------------------------- /src/Omnipay/Netpay/ExpressGateway.php: -------------------------------------------------------------------------------- 1 | 9 | **/ 10 | class ExpressGateway extends AbstractGateway { 11 | 12 | /** 13 | * Get gateway display name 14 | * 15 | * This can be used by carts to get the display name for each gateway. 16 | */ 17 | public function getName() 18 | { 19 | return 'Netpay_Express'; 20 | } 21 | 22 | function setKey($filepath) 23 | { 24 | $this->setParameter('key_file', $filepath); 25 | } 26 | 27 | function getKey() 28 | { 29 | return $this->getParameter('key_file'); 30 | } 31 | 32 | function setCert($filepath) 33 | { 34 | $this->setParameter('cert_file', $filepath); 35 | } 36 | 37 | function getCert() 38 | { 39 | $this->getParameter('cert_file'); 40 | } 41 | 42 | function getPartner() 43 | { 44 | return $this->getParameter('partner'); 45 | } 46 | 47 | function setPartner($id) 48 | { 49 | $this->setParameter('partner', $id); 50 | } 51 | 52 | function getNotifyUrl() 53 | { 54 | return $this->getParameter('notify_url'); 55 | } 56 | 57 | function setNotifyUrl($url) 58 | { 59 | $this->setParameter('notify_url', $url); 60 | } 61 | 62 | function setReturnUrl($url) 63 | { 64 | $this->setParameter('return_url', $url); 65 | } 66 | 67 | function getReturnUrl($url) 68 | { 69 | return $this->getParameter('return_url'); 70 | } 71 | 72 | /** 73 | * Define gateway parameters, in the following format: 74 | * 75 | * array( 76 | * 'username' => '', // string variable 77 | * 'testMode' => false, // boolean variable 78 | * 'landingPage' => array('billing', 'login'), // enum variable, first item is default 79 | * ); 80 | */ 81 | public function getDefaultParameters() 82 | { 83 | return [ 84 | 85 | ]; 86 | } 87 | 88 | public function purchase(array $parameters = []) 89 | { 90 | return $this->createRequest('\Omnipay\Netpay\Message\NetpayPurchaseRequest', $parameters); 91 | } 92 | 93 | public function completePurchase(array $parameters = array()) 94 | { 95 | return $this->createRequest('\Omnipay\Netpay\Message\NetpayCompletePurchaseRequest', $parameters); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/BaseAbstractRequest.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | abstract class BaseAbstractRequest extends AbstractRequest { 12 | 13 | protected function getHttpResponseGET($url, $cacert_url) 14 | { 15 | $curl = curl_init($url); 16 | curl_setopt($curl, CURLOPT_HEADER, 0); 17 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 18 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); 19 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); 20 | curl_setopt($curl, CURLOPT_CAINFO, $cacert_url); 21 | $responseText = curl_exec($curl); 22 | curl_close($curl); 23 | return $responseText; 24 | } 25 | 26 | protected function postXml($xmlstr, $url, $cacert_url) 27 | { 28 | $ch = curl_init(); 29 | //超时时间 30 | curl_setopt($ch, CURLOPT_TIMEOUT, 30); 31 | //这里设置代理,如果有的话 32 | //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); 33 | //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); 34 | curl_setopt($ch, CURLOPT_URL, $url); 35 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 36 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 37 | //设置header 38 | curl_setopt($ch, CURLOPT_HEADER, FALSE); 39 | //要求结果为字符串且输出到屏幕上 40 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 41 | //设置证书 42 | //使用证书:cert 与 key 分别属于两个.pem文件 43 | //默认格式为PEM,可以注释 44 | curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); 45 | curl_setopt($ch, CURLOPT_SSLCERT, '/Users/gzhang/Desktop/cert/apiclient_cert.pem'); 46 | //默认格式为PEM,可以注释 47 | curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); 48 | curl_setopt($ch, CURLOPT_SSLKEY, '/Users/gzhang/Desktop/cert/apiclient_key.pem'); 49 | //post提交方式 50 | curl_setopt($ch, CURLOPT_POST, true); 51 | curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlstr); 52 | $data = curl_exec($ch); 53 | //返回结果 54 | if ($data) 55 | { 56 | curl_close($ch); 57 | return $data; 58 | } 59 | else 60 | { 61 | $error = curl_errno($ch); 62 | echo "curl出错,错误码:$error" . "
"; 63 | echo "错误原因查询
"; 64 | curl_close($ch); 65 | return false; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/BaseAbstractRequest.php: -------------------------------------------------------------------------------- 1 | getSignType())) { 22 | case "MD5": 23 | $sign = $this->md5Sign($query_string); 24 | break; 25 | case "RSA": 26 | $sign = $this->rsaSign($query_string, $this->getPrivateKey()); 27 | break; 28 | case "0001": 29 | $sign = $this->rsaSign($query_string, $this->getPrivateKey()); 30 | break; 31 | default: 32 | $sign = ''; 33 | } 34 | return $sign; 35 | } 36 | 37 | protected function rsaSign($data, $private_key_path) 38 | { 39 | $priKey = file_get_contents($private_key_path); 40 | $res = openssl_pkey_get_private($priKey); 41 | openssl_sign($data, $sign, $res); 42 | openssl_free_key($res); 43 | //base64编码 44 | $sign = base64_encode($sign); 45 | return $sign; 46 | } 47 | 48 | /** 49 | * @param $query_string 50 | * 51 | * @return string 52 | */ 53 | protected function md5Sign($query_string) 54 | { 55 | return md5($query_string . $this->getKey()); 56 | } 57 | 58 | public function getPrivateKey() 59 | { 60 | return $this->getParameter('private_key'); 61 | } 62 | 63 | public function setPrivateKey($value) 64 | { 65 | $this->setParameter('private_key', $value); 66 | } 67 | 68 | public function getKey() 69 | { 70 | return $this->getParameter('key'); 71 | } 72 | 73 | public function setKey($value) 74 | { 75 | $this->setParameter('key', $value); 76 | } 77 | 78 | public function getSignType() 79 | { 80 | return $this->getParameter('sign_type'); 81 | } 82 | 83 | public function setSignType($value) 84 | { 85 | if (in_array($value, array('md5', 'rsa'))) { 86 | throw new Exception('sign_type should be upper case'); 87 | } 88 | $this->setParameter('sign_type', $value); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/UnifiedOrder.php: -------------------------------------------------------------------------------- 1 | url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 11 | //设置curl超时时间 12 | $this->curl_timeout = static::CURL_TIMEOUT; 13 | } 14 | 15 | /** 16 | * 生成接口参数xml 17 | */ 18 | function createXml() 19 | { 20 | try 21 | { 22 | //检测必填参数 23 | if ($this->parameters["out_trade_no"] == null) 24 | { 25 | throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!" . "
"); 26 | } 27 | elseif ($this->parameters["body"] == null) 28 | { 29 | throw new SDKRuntimeException("缺少统一支付接口必填参数body!" . "
"); 30 | } 31 | elseif ($this->parameters["total_fee"] == null) 32 | { 33 | throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!" . "
"); 34 | } 35 | elseif ($this->parameters["notify_url"] == null) 36 | { 37 | throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!" . "
"); 38 | } 39 | elseif ($this->parameters["trade_type"] == null) 40 | { 41 | throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!" . "
"); 42 | } 43 | elseif ($this->parameters["trade_type"] == "JSAPI" && 44 | $this->parameters["openid"] == NULL 45 | ) 46 | { 47 | throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "
"); 48 | } 49 | $this->parameters["appid"] = $this->app_id; //公众账号ID 50 | $this->parameters["mch_id"] = $this->mch_id; //商户号 51 | $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR']; //终端ip 52 | $this->parameters["nonce_str"] = $this->createNoncestr(); //随机字符串 53 | $this->parameters["sign"] = $this->getSign($this->parameters); //签名 54 | return $this->arrayToXml($this->parameters); 55 | } catch (SDKRuntimeException $e) 56 | { 57 | die($e->errorMessage()); 58 | } 59 | } 60 | 61 | /** 62 | * 获取prepay_id 63 | */ 64 | function getPrepayId() 65 | { 66 | $this->postXml(); 67 | $this->result = $this->xmlToArray($this->response); 68 | $prepay_id = isset($this->result["prepay_id"]) ? $this->result['prepay_id'] : false; 69 | return $prepay_id; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /demo/alipay.notify.php: -------------------------------------------------------------------------------- 1 | setPartner($config['partner']); 20 | $gateway->setKey($config['key']); 21 | $gateway->setSellerEmail($config['seller_email']); 22 | 23 | $params = array_merge($get, $post); 24 | 25 | $options['ca_cert_path'] = $config['ca_cert_path']; 26 | $options['sign_type'] = 'MD5'; 27 | $options['request_params'] = $params; 28 | 29 | $cache->save(LAST_NOTIFY_CACHE_KEY, array( 30 | 'url' => 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 31 | 'get' => http_build_query($get), 'post' => http_build_query($post) 32 | )); 33 | 34 | $response = $gateway->completePurchase($options)->send(); 35 | if ($response->isSuccessful() && $response->isTradeStatusOk()) 36 | { 37 | //todo success 38 | // if u use the wap alipay u need to parse the trade info from .notify_data 39 | $params = \Omnipay\Utils\Utils::format_wap_alipay_notify($params); 40 | $no = $params['out_trade_no']; 41 | $opts = $cache->fetch($no); 42 | $opts['notify'] = array('_GET' => $get, '_POST' => $post); 43 | $opts['status'] = '支付成功'; 44 | 45 | $cache->delete(LAST_ERROR_CACHE_KEY); 46 | $cache->save(LAST_NOTIFY_CACHE_KEY, array( 47 | 'url' => 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 48 | 'get' => http_build_query($get), 'post' => http_build_query($post), 49 | 'out_trade_no' => $no, 50 | 'status' => 'success' 51 | )); 52 | 53 | $cache->save($no, $opts); 54 | 55 | // success return 'success' to response to tell alipay's server, to stop continuing notify request 56 | // die('continue') //return continue just for debug; 57 | die('success'); 58 | } 59 | else 60 | { 61 | $cache->save(LAST_ERROR_CACHE_KEY, $options); 62 | die('fail'); 63 | } 64 | } catch (\Exception $e) 65 | { 66 | $cache->save(LAST_ERROR_CACHE_KEY, $e->getLine() . ': ' . $e->getMessage()); 67 | die('exception'); 68 | } 69 | } 70 | 71 | notify_callback($config, $_GET, $_POST); -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 11 | **/ 12 | class WechatPurchaseRequest extends BaseAbstractRequest { 13 | 14 | protected function getParameter($key) 15 | { 16 | return $this->parameters->get($key); 17 | } 18 | 19 | public function initialize(array $parameters = array()) 20 | { 21 | if (null !== $this->response) 22 | { 23 | throw new \RuntimeException('Request cannot be modified after it has been sent!'); 24 | } 25 | 26 | $this->parameters = new ParameterBag; 27 | foreach ($parameters as $k => $v) 28 | { 29 | $this->parameters->set($k, $v); 30 | } 31 | return $this; 32 | } 33 | 34 | 35 | /** 36 | * Get the raw data array for this message. The format of this varies from gateway to 37 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 38 | * 39 | * @return mixed 40 | */ 41 | public function getData() 42 | { 43 | $this->validate( 44 | 'app_id', 45 | 'productid', 46 | 'app_key' 47 | ); 48 | 49 | $params = $this->parameters->all(); 50 | $params['appid'] = $params['app_id']; 51 | $params['appkey'] = $params['app_key']; 52 | $params['mch_id'] = $params['partner']; 53 | $params = array_only($params, array( 54 | 'appid', 'productid', 'appkey', 55 | 'noncestr', 'timestamp', 'package','mch_id' 56 | )); 57 | 58 | 59 | return $params; 60 | } 61 | 62 | /** 63 | * Send the request with specified data 64 | * 65 | * @param mixed $data The data to send 66 | * @return ResponseInterface 67 | */ 68 | public function sendData($data) 69 | { 70 | $this->response = new WechatPurchaseResponse($this, $data); 71 | if ($this->parameters->has('return_url')) 72 | { 73 | $this->response->setReturnUrl($this->parameters->get('return_url')); 74 | } 75 | if ($this->parameters->has('return_url')) 76 | { 77 | $this->response->setCancelUrl($this->parameters->get('cancel_url')); 78 | } 79 | if ($this->parameters->has('fail_url')) 80 | { 81 | $this->response->setFailUrl($this->parameters->get('fail_url')); 82 | } 83 | return $this->response; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/WapExpressPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | %s', 25 | $this->getToken() 26 | ); 27 | /************************************************************/ 28 | //构造要请求的参数数组,无需改动 29 | $data = array( 30 | "service" => "alipay.wap.auth.authAndExecute", 31 | "partner" => $this->getPartner(), 32 | "sec_id" => $this->getSignType(), 33 | "format" => 'xml', 34 | "v" => '2.0', 35 | "req_id" => microtime(true) . '', 36 | "req_data" => $req_data, 37 | "_input_charset" => $this->getInputCharset() 38 | ); 39 | $data['sign'] = $this->getParamsSignature($data); 40 | return $data; 41 | } 42 | 43 | public function getKey() 44 | { 45 | return $this->getParameter('key'); 46 | } 47 | 48 | public function setKey($value) 49 | { 50 | $this->setParameter('key', $value); 51 | } 52 | 53 | public function getInputCharset() 54 | { 55 | return $this->getParameter('input_charset'); 56 | } 57 | 58 | public function setInputCharset($value) 59 | { 60 | $this->setParameter('input_charset', $value); 61 | } 62 | 63 | public function getSignType() 64 | { 65 | return $this->getParameter('sign_type'); 66 | } 67 | 68 | public function setSignType($value) 69 | { 70 | $this->setParameter('sign_type', $value); 71 | } 72 | 73 | public function getPartner() 74 | { 75 | return $this->getParameter('partner'); 76 | } 77 | 78 | public function setPartner($value) 79 | { 80 | $this->setParameter('partner', $value); 81 | } 82 | 83 | public function sendData($data) 84 | { 85 | return $this->response = new WapExpressPurchaseResponse($this, $data); 86 | } 87 | 88 | public function getEndpoint() 89 | { 90 | return $this->endpoint; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Omnipay/Cmpay/Message/ExpressPurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 12 | **/ 13 | class ExpressPurchaseResponse extends AbstractResponse implements RedirectResponseInterface { 14 | 15 | protected $endpoint = 'https://ipos.10086.cn/ips/cmpayService'; 16 | 17 | private $redirectMethod = 'GET'; 18 | 19 | /** 20 | * Gets the redirect target url. 21 | */ 22 | public function getRedirectUrl() 23 | { 24 | $data = $this->getData(); 25 | $params = array_except($data, 'merchantKey'); 26 | $merchantKey = $data['merchantKey']; 27 | 28 | $sTotalString = Utils::POSTDATA($this->endpoint, $params); 29 | 30 | $recv = $sTotalString["MSG"]; 31 | $recv = iconv('gb2312', 'utf-8', $recv); 32 | $recvArray = Utils::parseRecv($recv); 33 | 34 | $code = $recvArray["returnCode"]; 35 | $payUrl = false; 36 | if ($code != "000000") 37 | { 38 | // echo "code:" . $code . "
msg:" . decodeUtf8($recvArray["message"]); 39 | return $code.':'.$recvArray["message"]; 40 | } 41 | else 42 | { 43 | $vfsign = $recvArray["merchantId"] . $recvArray["requestId"] 44 | . $recvArray["signType"] . $recvArray["type"] 45 | . $recvArray["version"] . $recvArray["returnCode"] 46 | . $recvArray["message"] . $recvArray["payUrl"]; 47 | $hmac = Utils::MD5sign($merchantKey, $vfsign); 48 | $vhmac = $recvArray["hmac"]; 49 | if ($hmac != $vhmac) 50 | { 51 | echo "验证签名失败!"; 52 | exit(); 53 | } 54 | else 55 | { 56 | $payUrl = $recvArray["payUrl"]; 57 | //返回url处理 58 | $rpayUrl = Utils::parseUrl($payUrl); 59 | $payUrl = $rpayUrl['url']; 60 | $this->redirectMethod = $rpayUrl['method']; 61 | } 62 | } 63 | return $payUrl; 64 | } 65 | 66 | /** 67 | * Get the required redirect method (either GET or POST). 68 | */ 69 | public function getRedirectMethod() 70 | { 71 | return $this->redirectMethod; 72 | } 73 | 74 | /** 75 | * Gets the redirect form data array, if the redirect method is POST. 76 | */ 77 | public function getRedirectData() 78 | { 79 | return []; 80 | } 81 | 82 | /** 83 | * Is the response successful? 84 | * 85 | * @return boolean 86 | */ 87 | public function isSuccessful() 88 | { 89 | return true; 90 | } 91 | 92 | public function isRedirect() 93 | { 94 | return true; 95 | } 96 | 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/ExpressPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | validate( 16 | 'total_fee' 17 | ); 18 | } 19 | 20 | /** 21 | * Get the raw data array for this message. The format of this varies from gateway to 22 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 23 | * 24 | * @return mixed 25 | */ 26 | public function getData() 27 | { 28 | $this->validateData(); 29 | $data = array( 30 | "service" => $this->getService(), 31 | "partner" => $this->getPartner(), 32 | "payment_type" => 1, 33 | "notify_url" => $this->getNotifyUrl(), 34 | "return_url" => $this->getReturnUrl(), 35 | "seller_email" => $this->getSellerEmail(), 36 | "out_trade_no" => $this->getOutTradeNo(), 37 | "subject" => $this->getSubject(), 38 | "total_fee" => $this->getTotalFee(), 39 | "currency" => $this->getCurrency(), 40 | "body" => $this->getBody(), 41 | "show_url" => $this->getShowUrl(), 42 | "anti_phishing_key" => $this->getAntiPhishingKey(), 43 | "exter_invoke_ip" => $this->getExterInvokeIp(), 44 | "paymethod" => $this->getPayMethod(), 45 | "defaultbank" => $this->getDefaultBank(), 46 | "_input_charset" => $this->getInputCharset(), 47 | ); 48 | $data = array_filter($data); 49 | $data['sign'] = $this->getParamsSignature($data); 50 | $data['sign_type'] = $this->getSignType(); 51 | return $data; 52 | } 53 | 54 | public function getTotalFee() 55 | { 56 | return $this->getParameter('total_fee'); 57 | } 58 | 59 | public function setTotalFee($value) 60 | { 61 | $this->setParameter('total_fee', $value); 62 | } 63 | 64 | public function getCurrency() 65 | { 66 | return $this->getParameter('currency'); 67 | } 68 | 69 | public function setCurrency($value) 70 | { 71 | $this->setParameter('currency', $value); 72 | } 73 | 74 | public function getDefaultBank() 75 | { 76 | return $this->getParameter('default_bank'); 77 | } 78 | 79 | public function setDefaultBank($value) 80 | { 81 | $this->setParameter('default_bank', $value); 82 | } 83 | 84 | public function getPayMethod() 85 | { 86 | return $this->getParameter('pay_method'); 87 | } 88 | 89 | public function setPayMethod($value) 90 | { 91 | $this->setParameter('pay_method', $value); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /demo/wechat.notify.php: -------------------------------------------------------------------------------- 1 | setAppId($config['app_id']); 21 | $gateway->setKey($config['pay_sign_key']); 22 | $gateway->setPartner($config['partner']); 23 | $gateway->setPartnerKey($config['partner_key']); 24 | 25 | $gateway->setNotifyUrl($config['notify_url']); 26 | $gateway->setReturnUrl($config['return_url']); 27 | $gateway->setReturnUrl($config['cancel_url']); 28 | 29 | $out_trade_no = time() . rand(1000, 9999); 30 | $opts = array( 31 | 'subject' => "你正在为订单[$out_trade_no]支付...", 32 | 'description' => '微信无效', 33 | 'total_fee' => 0.01, 34 | 'out_trade_no' => $out_trade_no, 35 | ); 36 | $res = $gateway->purchase($opts)->send(); 37 | $cache = get_cache(); 38 | $cache->save($out_trade_no, $opts); 39 | 40 | if (!empty($_GET['redirect'])) 41 | { 42 | $res->redirect('js'); 43 | } 44 | $res->redirect(); 45 | } catch (\Exception $e) 46 | { 47 | var_dump($e->getMessage()); 48 | } 49 | } 50 | 51 | function notify_callback($config, $get, $raw_post) 52 | { 53 | $cache = get_cache(); 54 | try 55 | { 56 | $gateway = new \Omnipay\Wechat\ExpressGateway(); 57 | 58 | $gateway->setAppId($config['app_id']); 59 | $gateway->setKey($config['pay_sign_key']); 60 | $gateway->setPartner($config['partner']); 61 | $gateway->setPartnerKey($config['partner_key']); 62 | 63 | $cache->save(LAST_NOTIFY_CACHE_KEY, func_get_args()); 64 | $response = $gateway->completePurchase(array('request_params' => $get, 'body' => $raw_post))->send(); 65 | if ($response->isSuccessful() && $response->isTradeStatusOk()) 66 | { 67 | //todo success 68 | 69 | $serial = $cache->fetch($get['out_trade_no']); 70 | $serial['notify'] = array('status' => 'success', 'param' => http_build_query($get), 'body' => $raw_post); 71 | $data = json_decode(json_encode(simplexml_load_string($raw_post, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 72 | $cache->save($get['out_trade_no'], $serial); 73 | 74 | $cache->save(LAST_NOTIFY_CACHE_KEY, array( 75 | 'param' => http_build_query($get), 'body' => $raw_post, 76 | 'data' => $data, 77 | 'status' => $response->getMessage())); 78 | $cache->delete(LAST_ERROR_CACHE_KEY); 79 | 80 | die($response->getMessage()); 81 | // die('success'); 82 | } 83 | else 84 | { 85 | die($response->getMessage()); 86 | } 87 | } catch (\Exception $e) 88 | { 89 | $cache->save(LAST_ERROR_CACHE_KEY, $e->getLine() . ': ' . $e->getMessage()); 90 | die('exception: '. $e->getLine() . ' - ' . $e->getMessage()); 91 | } 92 | } 93 | 94 | notify_callback($config, $_GET, empty($_POST) ? file_get_contents('php://input') : $_POST); -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/JsApi.php: -------------------------------------------------------------------------------- 1 | curl_timeout = static::CURL_TIMEOUT; 18 | } 19 | 20 | /** 21 | * 作用:生成可以获得code的url 22 | */ 23 | function createOauthUrlForCode($redirectUrl) 24 | { 25 | $urlObj["appid"] = $this->app_id; 26 | $urlObj["redirect_uri"] = "$redirectUrl"; 27 | $urlObj["response_type"] = "code"; 28 | $urlObj["scope"] = "snsapi_base"; 29 | $urlObj["state"] = "STATE" . "#wechat_redirect"; 30 | $bizString = $this->formatBizQueryParaMap($urlObj, false); 31 | return "https://open.weixin.qq.com/connect/oauth2/authorize?" . $bizString; 32 | } 33 | 34 | /** 35 | * 作用:生成可以获得openid的url 36 | */ 37 | function createOauthUrlForOpenid() 38 | { 39 | $urlObj["appid"] = $this->app_id; 40 | // $urlObj["secret"] = WxPayConf_pub::APPSECRET; 41 | $urlObj["secret"] = $this->app_secret; 42 | $urlObj["code"] = $this->code; 43 | $urlObj["grant_type"] = "authorization_code"; 44 | $bizString = $this->formatBizQueryParaMap($urlObj, false); 45 | return "https://api.weixin.qq.com/sns/oauth2/access_token?" . $bizString; 46 | } 47 | 48 | 49 | /** 50 | * 作用:通过curl向微信提交code,以获取openid 51 | */ 52 | function getOpenid() 53 | { 54 | $url = $this->createOauthUrlForOpenid(); 55 | //初始化curl 56 | $ch = curl_init(); 57 | //设置超时 58 | // curl_setopt($ch, CURLOP_TIMEOUT, $this->curl_timeout); 59 | curl_setopt($ch, CURLOPT_URL, $url); 60 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 61 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 62 | curl_setopt($ch, CURLOPT_HEADER, FALSE); 63 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 64 | //运行curl,结果以jason形式返回 65 | $res = curl_exec($ch); 66 | curl_close($ch); 67 | //取出openid 68 | $data = json_decode($res, true); 69 | $this->openid = $data['openid']; 70 | return $this->openid; 71 | } 72 | 73 | /** 74 | * 作用:设置prepay_id 75 | */ 76 | function setPrepayId($prepayId) 77 | { 78 | $this->prepay_id = $prepayId; 79 | } 80 | 81 | /** 82 | * 作用:设置code 83 | */ 84 | function setCode($code_) 85 | { 86 | $this->code = $code_; 87 | } 88 | 89 | /** 90 | * 作用:设置jsapi的参数 91 | */ 92 | public function getParameters() 93 | { 94 | $jsApiObj["appId"] = $this->app_id; 95 | $timeStamp = time(); 96 | $jsApiObj["timeStamp"] = "$timeStamp"; 97 | $jsApiObj["nonceStr"] = $this->createNoncestr(); 98 | $jsApiObj["package"] = "prepay_id=$this->prepay_id"; 99 | $jsApiObj["signType"] = "MD5"; 100 | $jsApiObj["paySign"] = $this->getSign($jsApiObj); 101 | $this->parameters = json_encode($jsApiObj); 102 | 103 | return $this->parameters; 104 | } 105 | } -------------------------------------------------------------------------------- /src/Omnipay/Baifu/Message/ExpressPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 12 | **/ 13 | class ExpressPurchaseRequest extends AbstractRequest { 14 | 15 | protected function getParameter($key, $default = '') 16 | { 17 | return $this->parameters->get($key, $default); 18 | } 19 | 20 | public function initialize(array $parameters = array()) 21 | { 22 | if (null !== $this->response) 23 | { 24 | throw new \RuntimeException('Request cannot be modified after it has been sent!'); 25 | } 26 | 27 | $this->parameters = new ParameterBag; 28 | foreach ($parameters as $k => $v) 29 | { 30 | $this->parameters->set($k, $v); 31 | } 32 | return $this; 33 | } 34 | 35 | /** 36 | * Get the raw data array for this message. The format of this varies from gateway to 37 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 38 | * 39 | * @return mixed 40 | */ 41 | public function getData() 42 | { 43 | $this->validate( 44 | 'key', 45 | 'partner_id', 46 | 'out_trade_no', 47 | 'subject', 48 | 'total_fee' 49 | ); 50 | // $character_set = $this->getParameter('character_set', 'GBK'); 51 | $sp_pass_through = $this->getParameter('sp_pass_through', false); 52 | $bank_no = $this->getParameter('bank_no', false); 53 | $params = [ 54 | 'service_code' => 1, 55 | 'sp_no' => $this->getParameter('partner_id'), 56 | 'order_create_time' => date('YmdHis'), 57 | 'order_no' => $this->getParameter('out_trade_no'), 58 | 'goods_name' => $this->getParameter('subject'), 59 | 'goods_desc' => $this->getParameter('body', ''), 60 | 'total_amount' => $this->getParameter('total_fee')*100, 61 | 'currency' => 1, 62 | 'return_url' => $this->getParameter('notify_url'), 63 | 'page_url' => $this->getParameter('return_url'), 64 | 'pay_type' => $this->getParameter('type', 1), 65 | 'sign_method' => 1, 66 | 'input_charset' => 1, 67 | 'extra' => $this->getParameter('extra', ''), 68 | 'version' => 2 69 | ]; 70 | if($sp_pass_through) 71 | { 72 | $params['sp_pass_through'] = $sp_pass_through; 73 | } 74 | if($bank_no) 75 | { 76 | $params['bank_no'] = $bank_no; 77 | } 78 | ksort($params); 79 | $sign_str = ''; 80 | foreach($params as $k => $v) 81 | { 82 | $sign_str .= "$k=$v&"; 83 | } 84 | $sign_str = $sign_str . 'key=' . $this->getParameter('key'); 85 | $params['sign'] = md5($sign_str); 86 | return $params; 87 | } 88 | 89 | /** 90 | * Send the request with specified data 91 | * 92 | * @param mixed $data The data to send 93 | * @return ResponseInterface 94 | */ 95 | public function sendData($data) 96 | { 97 | $this->response = new ExpressPurchaseResponse($this, $data); 98 | return $this->response; 99 | } 100 | } -------------------------------------------------------------------------------- /HOWTO.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HOWTO 6 | 7 | 8 | 9 | 10 | 11 | 32 | 33 | 38 | 39 | 40 |
 41 | Demo Entry 演示入口
 42 | 
 43 | demo/index.php : 为demo的入口地址,可以测试支付宝支付,微信支付需要填入相关配置,支付宝配置已经填入
 44 | 
 45 | demo/config.php : 包含了一些通用配置,例如加载库,所需要库在vendor目录里,通过文件中:
 46 |     require_once('../vendor/autoload.php'); 语句加载
 47 | 
 48 | --------------------------------------------------------------------------------
 49 | Modify Alipay/Wechat Config 修改配置
 50 | 
 51 | 修改文件demo/config.php的返回值可修改配置
 52 | 
 53 | --------------------------------------------------------------------------------
 54 | 
 55 | About alipay.wap use:
 56 | 
 57 | demo/alipay.redirect.php : the demo for redirect use 关于如何跳转到支付界面的代码演示
 58 | 
 59 | demo/alipay.notify.php : the demo for notify use 关于如何响应通知的演示
 60 | 
 61 | the return url have the same params as alipay server post to demo/alipay.notify.php when
 62 | the return url call.
 63 |     当用户支付完成后,返回到return_url指定的路径时,所含参数阿里服务器通知支付结果到alipay.notify.php时,
 64 |     POST的参数一致。
 65 |     微信使用:
 66 |         $_GET['out_trade_no']: 为订单号,
 67 |         $_GET['trade_no']: 为流水号,
 68 |         $_GET['total_fee']为订单金额
 69 | 
 70 | ----------------------------------------------------------------------------------
 71 | 
 72 | About WeChat:
 73 | 
 74 | demo/wechat.redirect.php
 75 |     show how to redirect to pay by Wechat 支付跳转演示
 76 |     注意:这里输入的金额单位以元(接口做了处理,使得网关跳转接口一致使用元作为单位,但微信实际使用“分”
 77 |     做单位,因此在响应接口中,微信返回的金额单位为:“分”,不是元)
 78 | 
 79 | demo/wechat.notify.php
 80 |     show how to react the payment result notify. 响应支付结果
 81 | 
 82 | About return_url:
 83 |     支付完成跳转回来,微信使用POST,其参数与[demo/wechat.notify.php]一致。
 84 |     微信使用:
 85 |        $_GET['out_trade_no'] 订单号,
 86 |        $_GET['bank_billno'] 流水号,
 87 |        $_GET['product_fee'] 订单金额(单位为分, 注意这里单位与跳转的时候使用的不一致)
 88 |     通知/返回 url的其他参数:
 89 |        $_GET['notify_id'] 消息id
 90 |        $_GET['transaction_id'] 交易号
 91 | 
 92 | ---------------------------------------------------------------------------------
 93 | 通过demo/info.php?out_trade_no=xxxxxxxxxx可以查看支付状态, 返回为一个JSON, 里面记录了
 94 |     指定订单号(out_trade_no)的支付情况(跳转时使用的参数)
 95 |     last_notify: 上一次支付通知的记录(包括通知的url,以及$_GET, $_POST内容)
 96 |     last_error: 上一次支付通知失败纪录
 97 | 
 98 | 
99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /demo/wechat.redirect.php: -------------------------------------------------------------------------------- 1 | setAppId($config['app_id']); 30 | $gateway->setKey($config['pay_sign_key']); 31 | $gateway->setPartner($config['partner']); 32 | $gateway->setPartnerKey($config['partner_key']); 33 | 34 | $gateway->setNotifyUrl($config['notify_url']); 35 | $gateway->setReturnUrl($config['return_url']); 36 | $gateway->setReturnUrl($config['cancel_url']); 37 | 38 | $gateway->setCertPath($config['cert_path']); 39 | $gateway->setCertKeyPath($config['cert_key_path']); 40 | 41 | $out_trade_no = $_GET['out_trade_no']; 42 | $opts = array( 43 | 'open_id' => array_get($config, 'open_id', false), 44 | 'subject' => $_GET['subject'], 45 | 'description' => '微信无效', 46 | 'total_fee' => $_GET['total_fee'], 47 | 'out_trade_no' => $out_trade_no, 48 | ); 49 | if($type == 'prepay') 50 | { 51 | $res = $gateway->prePurchase(array_add($opts, 'trade_type', 'APP'))->send(); 52 | echo json_encode($res->getTransactionReference()); 53 | exit(0); 54 | }else{ 55 | $res = $gateway->purchase($opts)->send(); 56 | } 57 | 58 | // $res = $gateway->prePurchase($opts)->send(); 59 | // $ret = $res->getTransactionReference(); 60 | // echo $ret; 61 | $cache = get_cache(); 62 | $cache->save($out_trade_no, $opts); 63 | 64 | if (!empty($_GET['redirect'])) 65 | { 66 | $res->redirect('js'); 67 | } 68 | 69 | if (!empty($_GET['link'])) 70 | { 71 | $url = $res->getRedirectUrl(); 72 | if (empty($_GET['qr'])) 73 | { 74 | echo(""); 75 | echo("$url"); 76 | echo(""); 77 | } 78 | else 79 | { 80 | QRcode::png($url); 81 | } 82 | die(); 83 | } 84 | 85 | $res->redirect(); 86 | } catch (\Exception $e) 87 | { 88 | var_dump($e->getMessage()); 89 | } 90 | } 91 | 92 | if($_GET['pay_type'] == 'APP') 93 | { 94 | wechat_redirect($config, 'prepay'); 95 | exit(); 96 | } 97 | 98 | $jsApi = new \Omnipay\Wechat\Sdk\JsApi(); 99 | $jsApi->init(array( 100 | 'app_id' => $config['app_id'], 101 | 'mch_id' => $config['mch_id'], 102 | 'app_secret' => $config['app_secret'], 103 | 'pay_sign_key' => $config['pay_sign_key'], 104 | 'cert_path' => $config['cert_path'], 105 | 'cert_key_path' => $config['cert_key_path'], 106 | )); 107 | if (array_get($_GET, 'code', false)) 108 | { 109 | $jsApi->setCode($_GET['code']); 110 | // var_dump($_GET); 111 | // $url = $jsApi->createOauthUrlForOpenid(); 112 | //Header('Location: '. $url); 113 | $open_id = $jsApi->getOpenid(); 114 | $config['open_id'] = $open_id; 115 | // var_dump($open_id); 116 | wechat_redirect($config); 117 | } 118 | else 119 | { 120 | $r_link = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 121 | $url = $jsApi->createOauthUrlForCode(urlencode($r_link)); 122 | Header('Location: ' . $url); 123 | } 124 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/SecuredGateway.php: -------------------------------------------------------------------------------- 1 | setLogisticsFee($fee); 44 | $this->setLogisticsType($type); 45 | $this->setLogisticsPayment($payment); 46 | } 47 | 48 | public function getLogisticsFee() 49 | { 50 | return $this->getParameter('logistics_fee'); 51 | } 52 | 53 | public function setLogisticsFee($value) 54 | { 55 | $this->setParameter('logistics_fee', $value); 56 | } 57 | 58 | public function getLogisticsType() 59 | { 60 | return $this->getParameter('logistics_type'); 61 | } 62 | 63 | public function setLogisticsType($value) 64 | { 65 | $this->setParameter('logistics_type', $value); 66 | } 67 | 68 | public function getLogisticsPayment() 69 | { 70 | return $this->getParameter('logistics_payment'); 71 | } 72 | 73 | public function setLogisticsPayment($value) 74 | { 75 | $this->setParameter('logistics_payment', $value); 76 | } 77 | 78 | public function setReceiveInfo($name, $address, $zip, $phone, $mobile) 79 | { 80 | $this->setReceiveName($name); 81 | $this->setReceiveAddress($address); 82 | $this->setReceiveZip($zip); 83 | $this->setReceivePhone($phone); 84 | $this->setReceiveMobile($mobile); 85 | } 86 | 87 | public function getReceiveName() 88 | { 89 | return $this->getParameter('receive_name'); 90 | } 91 | 92 | public function setReceiveName($value) 93 | { 94 | $this->setParameter('receive_name', $value); 95 | } 96 | 97 | public function getReceiveAddress() 98 | { 99 | return $this->getParameter('receive_address'); 100 | } 101 | 102 | public function setReceiveAddress($value) 103 | { 104 | $this->setParameter('receive_address', $value); 105 | } 106 | 107 | public function getReceiveZip() 108 | { 109 | return $this->getParameter('receive_zip'); 110 | } 111 | 112 | public function setReceiveZip($value) 113 | { 114 | $this->setParameter('receive_zip', $value); 115 | } 116 | 117 | public function getReceivePhone() 118 | { 119 | return $this->getParameter('receive_phone'); 120 | } 121 | 122 | public function setReceivePhone($value) 123 | { 124 | $this->setParameter('receive_phone', $value); 125 | } 126 | 127 | public function getReceiveMobile() 128 | { 129 | return $this->getParameter('receive_mobile'); 130 | } 131 | 132 | public function setReceiveMobile($value) 133 | { 134 | $this->setParameter('receive_mobile', $value); 135 | } 136 | 137 | public function purchase(array $parameters = array()) 138 | { 139 | $this->setService($this->service_name); 140 | return $this->createRequest('\Omnipay\Alipay\Message\SecuredPurchaseRequest', $parameters); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatPrePurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 12 | **/ 13 | class WechatPrePurchaseRequest extends BaseAbstractRequest { 14 | 15 | protected $endpoint = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; 16 | 17 | protected function getParameter($key) 18 | { 19 | return $this->parameters->get($key); 20 | } 21 | 22 | public function initialize(array $parameters = array()) 23 | { 24 | if (null !== $this->response) 25 | { 26 | throw new \RuntimeException('Request cannot be modified after it has been sent!'); 27 | } 28 | 29 | $this->parameters = new ParameterBag; 30 | foreach ($parameters as $k => $v) 31 | { 32 | $this->parameters->set($k, $v); 33 | } 34 | return $this; 35 | } 36 | 37 | /** 38 | * Get the raw data array for this message. The format of this varies from gateway to 39 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 40 | * 41 | * @return mixed 42 | */ 43 | public function getData() 44 | { 45 | $this->validate( 46 | 'app_id', 47 | 'app_key', 48 | 'partner', 49 | 'body', 50 | 'out_trade_no', 51 | 'total_fee', 52 | 'spbill_create_ip', 53 | 'notify_url', 54 | 'cert_path', 55 | 'cert_key_path' 56 | ); 57 | 58 | $params = array_only($this->parameters->all(), array( 59 | 'app_id', 'app_key', 'partner', 60 | 'body', 'out_trade_no', 'total_fee', 61 | 'spbill_create_ip', 'notify_url', 'trade_type', 62 | 'open_id', 'product_id', 63 | 'device_info', 'attach', 64 | 'time_start', 'time_expire', 'goods_tag', 'cert_path', 'cert_key_path' 65 | )); 66 | $params['appid'] = $params['app_id']; 67 | $params['openid'] = $params['open_id']; 68 | $params['mch_id'] = $params['partner']; 69 | $params['nonstr'] = str_random(8); 70 | $params['time_start'] = date('YmdHis'); 71 | $params['trade_type'] = array_get($params, 'trade_type', 'JSAPI'); 72 | return array_except($params, ['app_id', 'open_id', 'partner']); 73 | } 74 | 75 | /** 76 | * Send the request with specified data 77 | * 78 | * @param mixed $data The data to send 79 | * @return ResponseInterface 80 | */ 81 | public function sendData($data) 82 | { 83 | $unifiedOrder = new UnifiedOrder(); 84 | $unifiedOrder->init(array( 85 | 'app_id' => $data['appid'], 86 | 'mch_id' => $data['mch_id'], 87 | 'app_secret' => '', 88 | 'pay_sign_key' => $data['app_key'], 89 | 'cert_path' => $data['cert_path'], 90 | 'cert_key_path' => $data['cert_key_path'], 91 | )); 92 | //sign已填,商户无需重复填写 93 | 94 | $unifiedOrder->setParameter('body', $data['body']); //商品描述 95 | $unifiedOrder->setParameter('out_trade_no', $data['out_trade_no']); //商户订单号 96 | $unifiedOrder->setParameter('total_fee', $data['total_fee']); //总金额 97 | $unifiedOrder->setParameter('notify_url', $data['notify_url']); //通知地址 98 | $unifiedOrder->setParameter('trade_type', $data['trade_type']); //交易类型 99 | if($data['trade_type'] == 'JSAPI') 100 | { 101 | $unifiedOrder->setParameter('openid', $data['openid']); 102 | } 103 | 104 | $ret = $unifiedOrder->getResult(); 105 | $this->response = new WechatPrePurchaseResponse($this, $ret); 106 | return $this->response; 107 | } 108 | 109 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/WapExpressGateway.php: -------------------------------------------------------------------------------- 1 | '', 34 | 'key' => '', 35 | 'signType' => 'MD5', 36 | 'inputCharset' => 'utf-8', 37 | ); 38 | } 39 | 40 | public function getSellerEmail() 41 | { 42 | return $this->getParameter('seller_email'); 43 | } 44 | 45 | public function setSellerEmail($value) 46 | { 47 | return $this->setParameter('seller_email', $value); 48 | } 49 | 50 | public function getPartner() 51 | { 52 | return $this->getParameter('partner'); 53 | } 54 | 55 | public function setPartner($value) 56 | { 57 | return $this->setParameter('partner', $value); 58 | } 59 | 60 | public function getKey() 61 | { 62 | return $this->getParameter('key'); 63 | } 64 | 65 | public function setKey($value) 66 | { 67 | return $this->setParameter('key', $value); 68 | } 69 | 70 | public function setNotifyUrl($value) 71 | { 72 | return $this->setParameter('notify_url', $value); 73 | } 74 | 75 | public function setReturnUrl($value) 76 | { 77 | return $this->setParameter('return_url', $value); 78 | } 79 | 80 | public function getCancelUrl() 81 | { 82 | return $this->getParameter('cancel_url'); 83 | } 84 | 85 | public function setCancelUrl($value) 86 | { 87 | return $this->setParameter('cancel_url', $value); 88 | } 89 | 90 | public function getSignType() 91 | { 92 | return $this->getParameter('sign_type'); 93 | } 94 | 95 | public function setSignType($value) 96 | { 97 | return $this->setParameter('sign_type', $value); 98 | } 99 | 100 | public function getInputCharset() 101 | { 102 | return $this->getParameter('input_charset'); 103 | } 104 | 105 | public function setInputCharset($value) 106 | { 107 | return $this->setParameter('input_charset', $value); 108 | } 109 | 110 | public function tokenRequest(array $parameters = array()) 111 | { 112 | $defaults = array(); 113 | $defaults['out_trade_no'] = '1'; 114 | $defaults['subject'] = '1'; 115 | $defaults['total_fee'] = '1'; 116 | $parameters = array_merge($defaults, $parameters); 117 | return $this->createRequest('\Omnipay\Alipay\Message\WapExpressAuthorizeRequest', $parameters); 118 | } 119 | 120 | public function purchase(array $parameters = array()) 121 | { 122 | /** 123 | * @var WapExpressAuthorizeResponse $response 124 | */ 125 | $response = $this->tokenRequest($parameters)->send(); 126 | if ($response->isSuccessful()) { 127 | $parameters['token'] = $response->getToken(); 128 | return $this->createRequest('\Omnipay\Alipay\Message\WapExpressPurchaseRequest', $parameters); 129 | } else { 130 | return $this->createRequest('\Omnipay\Alipay\Message\WapExpressPurchaseRequest', $parameters); 131 | } 132 | } 133 | 134 | public function completePurchase(array $parameters = array()) 135 | { 136 | return $this->createRequest('\Omnipay\Alipay\Message\WapExpressCompletePurchaseRequest', $parameters); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Omnipay/Baifu/Message/ExpressCompletePurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 12 | **/ 13 | class ExpressCompletePurchaseRequest extends AbstractRequest { 14 | 15 | protected $endpoint = 'https://www.baifubao.com/api/0/query/0/pay_result_by_order_no'; 16 | 17 | public $verifyResponse; 18 | 19 | protected function getParameter($key, $default = '') 20 | { 21 | return $this->parameters->get($key, $default); 22 | } 23 | 24 | public function initialize(array $parameters = array()) 25 | { 26 | if (null !== $this->response) 27 | { 28 | throw new \RuntimeException('Request cannot be modified after it has been sent!'); 29 | } 30 | 31 | $this->parameters = new ParameterBag; 32 | foreach ($parameters as $k => $v) 33 | { 34 | $this->parameters->set($k, $v); 35 | } 36 | return $this; 37 | } 38 | 39 | /** 40 | * Get the raw data array for this message. The format of this varies from gateway to 41 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 42 | * 43 | * @return mixed 44 | */ 45 | public function getData() 46 | { 47 | $this->validate( 48 | 'key', 49 | 'partner_id', 50 | 'out_trade_no' 51 | ); 52 | // $character_set = $this->getParameter('character_set', 'GBK'); 53 | $params = [ 54 | 'service_code' => 11, 55 | 'sp_no' => $this->getParameter('partner_id'), 56 | 'order_no' => $this->getParameter('out_trade_no'), 57 | 'output_type' => 1, 58 | 'output_charset' => 1, 59 | 'sign_method' => 1, 60 | 'version' => 2 61 | ]; 62 | ksort($params); 63 | $sign_str = ''; 64 | foreach ($params as $k => $v) 65 | { 66 | $sign_str .= "$k=$v&"; 67 | } 68 | $sign_str = $sign_str . 'key=' . $this->getParameter('key'); 69 | $params['sign'] = md5($sign_str); 70 | return $params; 71 | } 72 | 73 | /** 74 | * Send the request with specified data 75 | * 76 | * @param mixed $data The data to send 77 | * @return ResponseInterface 78 | */ 79 | public function sendData($data) 80 | { 81 | $verify_xml = $this->getVerifyResponse($data); 82 | /* */ 83 | $verify_xml = preg_replace('/<\?.*\?>/', '', $verify_xml); 84 | // $xml = simplexml_load_string($verify_xml, 'SimpleXMLElement', LIBXML_NOCDATA); 85 | $data = json_decode(json_encode(simplexml_load_string($verify_xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 86 | return $this->response = new ExpressCompletePurchaseResponse($this, $data); 87 | } 88 | 89 | protected function getVerifyResponse($data) 90 | { 91 | $verify_url = $this->endpoint; 92 | $verify_url = $verify_url . '?' . http_build_query($data) ; 93 | $responseTxt = $this->getHttpResponseGET($verify_url); 94 | return $responseTxt; 95 | } 96 | 97 | protected function getHttpResponseGET($url) 98 | { 99 | $curl = curl_init($url); 100 | curl_setopt($curl, CURLOPT_HEADER, 0); 101 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 102 | // curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); 103 | // curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); 104 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 105 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 106 | // curl_setopt($curl, CURLOPT_CAINFO, $cacert_url); 107 | $responseText = curl_exec($curl); 108 | curl_close($curl); 109 | return $responseText; 110 | } 111 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/BasePurchaseRequest.php: -------------------------------------------------------------------------------- 1 | validate( 19 | 'service', 20 | 'partner', 21 | 'key', 22 | 'seller_email', 23 | 'notify_url', 24 | 'return_url', 25 | 'out_trade_no', 26 | 'subject', 27 | 'input_charset' 28 | ); 29 | } 30 | 31 | public function getService() 32 | { 33 | return $this->getParameter('service'); 34 | } 35 | 36 | public function setService($value) 37 | { 38 | $this->setParameter('service', $value); 39 | } 40 | 41 | public function getOutTradeNo() 42 | { 43 | return $this->getParameter('out_trade_no'); 44 | } 45 | 46 | public function setOutTradeNo($value) 47 | { 48 | $this->setParameter('out_trade_no', $value); 49 | } 50 | 51 | public function getTransport() 52 | { 53 | return $this->getParameter('transport'); 54 | } 55 | 56 | public function setTransport($value) 57 | { 58 | $this->setParameter('transport', $value); 59 | } 60 | 61 | public function getAntiPhishingKey() 62 | { 63 | return $this->getParameter('anti_phishing_key'); 64 | } 65 | 66 | public function setAntiPhishingKey($value) 67 | { 68 | $this->setParameter('anti_phishing_key', $value); 69 | } 70 | 71 | public function getExterInvokeIp() 72 | { 73 | return $this->getParameter('exter_invoke_ip'); 74 | } 75 | 76 | public function setExterInvokeIp($value) 77 | { 78 | $this->setParameter('exter_invoke_ip', $value); 79 | } 80 | 81 | public function getBody() 82 | { 83 | return $this->getParameter('body'); 84 | } 85 | 86 | public function setBody($value) 87 | { 88 | $this->setParameter('body', $value); 89 | } 90 | 91 | public function getPartner() 92 | { 93 | return $this->getParameter('partner'); 94 | } 95 | 96 | public function setPartner($value) 97 | { 98 | $this->setParameter('partner', $value); 99 | } 100 | 101 | public function getShowUrl() 102 | { 103 | return $this->getParameter('show_url'); 104 | } 105 | 106 | public function setShowUrl($value) 107 | { 108 | $this->setParameter('show_url', $value); 109 | } 110 | 111 | public function getInputCharset() 112 | { 113 | return $this->getParameter('input_charset'); 114 | } 115 | 116 | public function setInputCharset($value) 117 | { 118 | $this->setParameter('input_charset', $value); 119 | } 120 | 121 | public function getNotifyUrl() 122 | { 123 | return $this->getParameter('notify_url'); 124 | } 125 | 126 | public function setNotifyUrl($value) 127 | { 128 | $this->setParameter('notify_url', $value); 129 | } 130 | 131 | public function getReturnUrl() 132 | { 133 | return $this->getParameter('return_url'); 134 | } 135 | 136 | public function setReturnUrl($value) 137 | { 138 | $this->setParameter('return_url', $value); 139 | } 140 | 141 | public function getSellerEmail() 142 | { 143 | return $this->getParameter('seller_email'); 144 | } 145 | 146 | public function setSellerEmail($value) 147 | { 148 | $this->setParameter('seller_email', $value); 149 | } 150 | 151 | public function getSubject() 152 | { 153 | return $this->getParameter('subject'); 154 | } 155 | 156 | public function setSubject($value) 157 | { 158 | $this->setParameter('subject', $value); 159 | } 160 | 161 | /** 162 | * Send the request with specified data 163 | * 164 | * @param mixed $data The data to send 165 | * 166 | * @return ResponseInterface 167 | */ 168 | public function sendData($data) 169 | { 170 | return $this->response = new PurchaseResponse($this, $data); 171 | } 172 | 173 | public function getEndpoint() 174 | { 175 | return $this->liveEndpoint; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatRefundRequest.php: -------------------------------------------------------------------------------- 1 | 13 | **/ 14 | class WechatRefundRequest extends BaseAbstractRequest { 15 | 16 | protected $endpoint = 'https://api.mch.weixin.qq.com/secapi/pay/refund'; 17 | 18 | const REFUND_SOURCE_UNSETTLED_FUNDS = 'REFUND_SOURCE_UNSETTLED_FUNDS'; 19 | const REFUND_SOURCE_RECHARGE_FUNDS = 'REFUND_SOURCE_RECHARGE_FUNDS'; 20 | 21 | protected function getParameter($key) 22 | { 23 | return $this->parameters->get($key); 24 | } 25 | 26 | public function initialize(array $parameters = array()) 27 | { 28 | if (null !== $this->response) 29 | { 30 | throw new \RuntimeException('Request cannot be modified after it has been sent!'); 31 | } 32 | 33 | $this->parameters = new ParameterBag; 34 | foreach ($parameters as $k => $v) 35 | { 36 | $this->parameters->set($k, $v); 37 | } 38 | return $this; 39 | } 40 | 41 | /** 42 | * Get the raw data array for this message. The format of this varies from gateway to 43 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 44 | * 45 | * @throws \Omnipay\Common\Exception\InvalidRequestException 46 | * @return mixed 47 | */ 48 | public function getData() 49 | { 50 | $this->validate( 51 | 'app_id', 52 | 'partner', 53 | 'app_key', 54 | 'out_refund_no', 55 | 'total_fee', 56 | 'refund_fee', 57 | 'cert_path', 58 | 'cert_key_path', 59 | 'pub_cert_path' 60 | ); 61 | $params = $this->parameters->all(); 62 | 63 | if (empty($params['transaction_id']) && empty($params['out_trade_no'])) 64 | { 65 | throw new InvalidRequestException("The transaction_id or out_trade_no parameter is required"); 66 | } 67 | $params['appid'] = $params['app_id']; 68 | $params['appkey'] = $params['app_key']; 69 | $params['mch_id'] = $params['partner']; 70 | $params['op_user_id'] = array_get($params, 'op_user_id', $params['partner']); 71 | $params['refund_account'] = array_get($params, 'refund_account', static::REFUND_SOURCE_RECHARGE_FUNDS); 72 | $params = array_only($params, array( 73 | 'appid', 'appkey', 74 | 'refund_fee', 'total_fee', 'out_trade_no', 75 | 'transaction_id', 'op_user_id', 'out_refund_no', 76 | 'noncestr', 'timestamp', 'mch_id', 'cert_path', 'cert_key_path', 'pub_cert_path', 'refund_account' 77 | )); 78 | return $params; 79 | } 80 | 81 | /** 82 | * Send the request with specified data 83 | * 84 | * @param mixed $data The data to send 85 | * @return ResponseInterface 86 | */ 87 | public function sendData($data) 88 | { 89 | $refund = new Refund(); 90 | $refund->init(array( 91 | 'app_id' => $data['appid'], 92 | 'mch_id' => $data['mch_id'], 93 | 'app_secret' => '', 94 | 'pay_sign_key' => $data['appkey'], 95 | 'cert_path' => $data['cert_path'], 96 | 'cert_key_path' => $data['cert_key_path'], 97 | 'pub_cert_path' => $data['pub_cert_path'] 98 | )); 99 | //sign已填,商户无需重复填写 100 | if (!empty($data['out_trade_no'])) 101 | { 102 | $refund->setParameter('out_trade_no', $data['out_trade_no']); //商户订单号 103 | } 104 | if (!empty($data['transaction_id'])) 105 | { 106 | $refund->setParameter('transaction_id', $data['transaction_id']); //商户订单号 107 | } 108 | $refund->setParameter('total_fee', $data['total_fee']); //总金额 109 | $refund->setParameter('refund_fee', $data['refund_fee']); //退款金额 110 | $refund->setParameter('out_refund_no', $data['out_refund_no']); //退款单号 111 | $refund->setParameter('op_user_id', $data['op_user_id']); //交易类型 112 | $refund->setParameter('refund_account', $data['refund_account']); 113 | 114 | $ret = $refund->getResult(); 115 | $this->response = new WechatRefundResponse($this, $ret); 116 | return $this->response; 117 | } 118 | } -------------------------------------------------------------------------------- /src/Omnipay/Cmpay/ExpressGateway.php: -------------------------------------------------------------------------------- 1 | 10 | **/ 11 | class ExpressGateway extends AbstractGateway { 12 | 13 | /** 14 | * Get gateway display name 15 | * 16 | * This can be used by carts to get the display name for each gateway. 17 | */ 18 | public function getName() 19 | { 20 | return 'CM_Express'; 21 | } 22 | 23 | /** 24 | * Define gateway parameters, in the following format: 25 | * 26 | * array( 27 | * 'username' => '', // string variable 28 | * 'testMode' => false, // boolean variable 29 | * 'landingPage' => array('billing', 'login'), // enum variable, first item is default 30 | * ); 31 | */ 32 | public function getDefaultParameters() 33 | { 34 | return [ 35 | 'character_set' => '02', 36 | 'sign_type' => 'MD5', 37 | 'request_id' => time(), 38 | 'type' => 'DirectPayConfirm', 39 | 'version' => '2.0.0' 40 | ]; 41 | } 42 | 43 | function setKey($filepath) 44 | { 45 | $this->setParameter('app_key', $filepath); 46 | } 47 | 48 | function getKey() 49 | { 50 | return $this->getParameter('app_key'); 51 | } 52 | 53 | function getPartner() 54 | { 55 | return $this->getParameter('app_id'); 56 | } 57 | 58 | function setPartner($id) 59 | { 60 | $this->setParameter('app_id', $id); 61 | } 62 | 63 | function getNotifyUrl() 64 | { 65 | return $this->getParameter('notify_url'); 66 | } 67 | 68 | function setNotifyUrl($url) 69 | { 70 | $this->setParameter('notify_url', $url); 71 | } 72 | 73 | function setReturnUrl($url) 74 | { 75 | $this->setParameter('return_url', $url); 76 | } 77 | 78 | function getReturnUrl($url) 79 | { 80 | return $this->getParameter('return_url'); 81 | } 82 | 83 | function setClientIP($ip) 84 | { 85 | $this->setParameter('client_ip', $ip); 86 | } 87 | 88 | function getClientIP() 89 | { 90 | return $this->getParameter('client_ip'); 91 | } 92 | 93 | public function purchase(array $parameters = []) 94 | { 95 | return $this->createRequest('\Omnipay\Cmpay\Message\ExpressPurchaseRequest', $parameters); 96 | } 97 | 98 | public function completePurchase(array $params = array()) 99 | { 100 | try 101 | { 102 | $merchantId = $params["merchantId"]; 103 | $payNo = $params["payNo"]; 104 | $returnCode = $params["returnCode"]; 105 | $message = $params["message"]; 106 | $signType = $params["signType"]; 107 | $type = $params["type"]; 108 | $version = $params["version"]; 109 | $amount = $params["amount"]; 110 | $amtItem = $params["amtItem"]; 111 | $bankAbbr = $params["bankAbbr"]; 112 | $mobile = $params["mobile"]; 113 | $orderId = $params["orderId"]; 114 | $payDate = $params["payDate"]; 115 | $accountDate = $params["accountDate"]; 116 | $reserved1 = $params["reserved1"]; 117 | $reserved2 = $params["reserved2"]; 118 | $status = $params["status"]; 119 | // $payType = $params["payType"]; 120 | $orderDate = $params["orderDate"]; 121 | $fee = $params["fee"]; 122 | $vhmac = $params["hmac"]; 123 | 124 | if ($returnCode != 000000) 125 | { 126 | //此处表示后台通知产生错误 127 | // echo $returnCode . decodeUtf8($message); 128 | return [ 129 | 'status' => false, 130 | 'message' => $returnCode . decodeUtf8($message) 131 | ]; 132 | } 133 | 134 | $signData = $merchantId . $payNo . $returnCode . $message 135 | . $signType . $type . $version . $amount 136 | . $amtItem . $bankAbbr . $mobile . $orderId 137 | . $payDate . $accountDate . $reserved1 . $reserved2 138 | . $status . $orderDate . $fee; 139 | $hmac = Utils::MD5sign($this->getParameter('app_key'), $signData); 140 | 141 | if ($hmac != $vhmac) 142 | //此处无法信息数据来自手机支付平台 143 | return [ 144 | 'status' => false, 145 | 'message' => '验签失败' 146 | ]; 147 | else 148 | { 149 | return [ 150 | 'status' => true, 151 | 'message' => 'SUCCESS' 152 | ]; 153 | } 154 | } catch (\Exception $e) 155 | { 156 | return ['status' => false, 'message' => $e->getLine() . ':' . $e->getMessage()]; 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/BaseAbstractGateway.php: -------------------------------------------------------------------------------- 1 | '', 17 | 'key' => '', 18 | 'signType' => 'MD5', 19 | 'inputCharset' => 'utf-8', 20 | 'transport' => 'http', 21 | ); 22 | } 23 | 24 | public function getPartner() 25 | { 26 | return $this->getParameter('partner'); 27 | } 28 | 29 | public function setPartner($value) 30 | { 31 | return $this->setParameter('partner', $value); 32 | } 33 | 34 | public function getKey() 35 | { 36 | return $this->getParameter('key'); 37 | } 38 | 39 | public function setKey($value) 40 | { 41 | return $this->setParameter('key', $value); 42 | } 43 | 44 | public function setNotifyUrl($value) 45 | { 46 | return $this->setParameter('notify_url', $value); 47 | } 48 | 49 | public function setReturnUrl($value) 50 | { 51 | return $this->setParameter('return_url', $value); 52 | } 53 | 54 | public function getSignType() 55 | { 56 | return $this->getParameter('sign_type'); 57 | } 58 | 59 | public function setSignType($value) 60 | { 61 | return $this->setParameter('sign_type', $value); 62 | } 63 | 64 | public function getInputCharset() 65 | { 66 | return $this->getParameter('input_charset'); 67 | } 68 | 69 | public function setInputCharset($value) 70 | { 71 | return $this->setParameter('input_charset', $value); 72 | } 73 | 74 | public function getTransport() 75 | { 76 | return $this->getParameter('transport'); 77 | } 78 | 79 | public function setTransport($value) 80 | { 81 | return $this->setParameter('transport', $value); 82 | } 83 | 84 | public function getAntiPhishingKey() 85 | { 86 | return $this->getParameter('anti_phishing_key'); 87 | } 88 | 89 | public function setAntiPhishingKey($value) 90 | { 91 | return $this->setParameter('anti_phishing_key', $value); 92 | } 93 | 94 | public function getExterInvokeIp() 95 | { 96 | return $this->getParameter('exter_invoke_ip'); 97 | } 98 | 99 | public function setExterInvokeIp($value) 100 | { 101 | return $this->setParameter('exter_invoke_ip', $value); 102 | } 103 | 104 | public function getBody() 105 | { 106 | return $this->getParameter('body'); 107 | } 108 | 109 | public function setBody($value) 110 | { 111 | return $this->setParameter('body', $value); 112 | } 113 | 114 | public function getShowUrl() 115 | { 116 | return $this->getParameter('show_url'); 117 | } 118 | 119 | public function setShowUrl($value) 120 | { 121 | return $this->setParameter('show_url', $value); 122 | } 123 | 124 | public function getSellerEmail() 125 | { 126 | return $this->getParameter('seller_email'); 127 | } 128 | 129 | public function setSellerEmail($value) 130 | { 131 | $this->setParameter('seller_email', $value); 132 | } 133 | 134 | public function getService() 135 | { 136 | return $this->getParameter('service'); 137 | } 138 | 139 | public function setService($value) 140 | { 141 | $this->setParameter('service', $value); 142 | } 143 | 144 | public function getDefaultBank() 145 | { 146 | return $this->getParameter('default_bank'); 147 | } 148 | 149 | public function setDefaultBank($value) 150 | { 151 | $this->setParameter('default_bank', $value); 152 | } 153 | 154 | public function getPayMethod() 155 | { 156 | return $this->getParameter('pay_method'); 157 | } 158 | 159 | public function setPayMethod($value) 160 | { 161 | $this->setParameter('pay_method', $value); 162 | } 163 | 164 | public function purchase(array $parameters = array()) 165 | { 166 | return $this->createRequest('\Omnipay\Alipay\Message\ExpressPurchaseRequest', $parameters); 167 | } 168 | 169 | /** 170 | * @param array $parameters exp: ['refund_data' => [ [ 'trade_no' => 'alipay trade no', 'total_fee' => 'the fee to refund', 'memo' => ''] ] ] 171 | * @throws \RuntimeException 172 | */ 173 | public function refund(array $parameters = array()) 174 | { 175 | throw new \RuntimeException('Do not support refund'); 176 | } 177 | 178 | public function completePurchase(array $parameters = array()) 179 | { 180 | return $this->createRequest('\Omnipay\Alipay\Message\ExpressCompletePurchaseRequest', $parameters); 181 | } 182 | 183 | public function completeRefund(array $parameters = array()) 184 | { 185 | return $this->createRequest('\Omnipay\Alipay\Message\ExpressCompleteRefundRequest', $parameters); 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/SecuredPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | validate( 16 | 'price', 17 | 'quantity', 18 | 'logistics_fee', 19 | 'logistics_type', 20 | 'receive_name', 21 | 'receive_address', 22 | 'receive_zip', 23 | 'receive_phone', 24 | 'receive_mobile' 25 | ); 26 | } 27 | 28 | /** 29 | * Get the raw data array for this message. The format of this varies from gateway to 30 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 31 | * 32 | * @return mixed 33 | */ 34 | public function getData() 35 | { 36 | $this->validateData(); 37 | $data = array( 38 | "service" => $this->getService(), 39 | "partner" => $this->getPartner(), 40 | "payment_type" => 1, 41 | "notify_url" => $this->getNotifyUrl(), 42 | "return_url" => $this->getReturnUrl(), 43 | "seller_email" => $this->getSellerEmail(), 44 | "out_trade_no" => $this->getOutTradeNo(), 45 | "subject" => $this->getSubject(), 46 | "price" => $this->getPrice(), 47 | "quantity" => $this->getQuantity(), 48 | "logistics_fee" => $this->getLogisticsFee(), 49 | "logistics_type" => $this->getLogisticsType(), 50 | "logistics_payment" => $this->getLogisticsPayment(), 51 | "body" => $this->getBody(), 52 | "show_url" => $this->getShowUrl(), 53 | "receive_name" => $this->getReceiveName(), 54 | "receive_address" => $this->getReceiveAddress(), 55 | "receive_zip" => $this->getReceiveZip(), 56 | "receive_phone" => $this->getReceivePhone(), 57 | "receive_mobile" => $this->getReceiveMobile(), 58 | "_input_charset" => $this->getInputCharset() 59 | ); 60 | $data = array_filter($data); 61 | $data['sign'] = $this->getParamsSignature($data); 62 | $data['sign_type'] = $this->getSignType(); 63 | return $data; 64 | } 65 | 66 | public function getPrice() 67 | { 68 | return $this->getParameter('price'); 69 | } 70 | 71 | public function setPrice($value) 72 | { 73 | $this->setParameter('price', $value); 74 | } 75 | 76 | public function getQuantity() 77 | { 78 | return $this->getParameter('quantity'); 79 | } 80 | 81 | public function setQuantity($value) 82 | { 83 | $this->setParameter('quantity', $value); 84 | } 85 | 86 | public function getLogisticsFee() 87 | { 88 | return $this->getParameter('logistics_fee'); 89 | } 90 | 91 | public function setLogisticsFee($value) 92 | { 93 | $this->setParameter('logistics_fee', $value); 94 | } 95 | 96 | public function getLogisticsType() 97 | { 98 | return $this->getParameter('logistics_type'); 99 | } 100 | 101 | public function setLogisticsType($value) 102 | { 103 | $this->setParameter('logistics_type', $value); 104 | } 105 | 106 | public function getLogisticsPayment() 107 | { 108 | return $this->getParameter('logistics_payment'); 109 | } 110 | 111 | public function setLogisticsPayment($value) 112 | { 113 | $this->setParameter('logistics_payment', $value); 114 | } 115 | 116 | public function getReceiveName() 117 | { 118 | return $this->getParameter('receive_name'); 119 | } 120 | 121 | public function setReceiveName($value) 122 | { 123 | $this->setParameter('receive_name', $value); 124 | } 125 | 126 | public function getReceiveAddress() 127 | { 128 | return $this->getParameter('receive_address'); 129 | } 130 | 131 | public function setReceiveAddress($value) 132 | { 133 | $this->setParameter('receive_address', $value); 134 | } 135 | 136 | public function getReceiveZip() 137 | { 138 | return $this->getParameter('receive_zip'); 139 | } 140 | 141 | public function setReceiveZip($value) 142 | { 143 | $this->setParameter('receive_zip', $value); 144 | } 145 | 146 | public function getReceivePhone() 147 | { 148 | return $this->getParameter('receive_phone'); 149 | } 150 | 151 | public function setReceivePhone($value) 152 | { 153 | $this->setParameter('receive_phone', $value); 154 | } 155 | 156 | public function getReceiveMobile() 157 | { 158 | return $this->getParameter('receive_mobile'); 159 | } 160 | 161 | public function setReceiveMobile($value) 162 | { 163 | $this->setParameter('receive_mobile', $value); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Omnipay/Cmpay/Utils.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | class Utils { 10 | 11 | 12 | /* 13 | 功能 发送HTTP请求 14 | URL 请求地址 15 | data 请求数据数组 16 | */ 17 | static function POSTDATA($url, $data) 18 | { 19 | $url = parse_url($url); 20 | if (!$url) 21 | { 22 | return "couldn't parse url"; 23 | } 24 | if (!isset($url['port'])) 25 | { 26 | $url['port'] = ""; 27 | } 28 | 29 | if (!isset($url['query'])) 30 | { 31 | $url['query'] = ""; 32 | } 33 | 34 | 35 | $encoded = ""; 36 | 37 | while (list($k, $v) = each($data)) 38 | { 39 | $encoded .= ($encoded ? "&" : ""); 40 | $encoded .= rawurlencode($k) . "=" . rawurlencode($v); 41 | } 42 | $urlHead = null; 43 | $urlPort = $url['port']; 44 | if ($url['scheme'] == "https") 45 | { 46 | $urlHead = "ssl://" . $url['host']; 47 | if ($url['port'] == null || $url['port'] == 0) 48 | { 49 | $urlPort = 443; 50 | } 51 | } 52 | else 53 | { 54 | $urlHead = $url['host']; 55 | if ($url['port'] == null || $url['port'] == 0) 56 | { 57 | $urlPort = 80; 58 | } 59 | } 60 | $fp = fsockopen($urlHead, $urlPort); 61 | 62 | if (!$fp) return "Failed to open socket to $url[host]"; 63 | 64 | $tmp = ""; 65 | $tmp .= sprintf("POST %s%s%s HTTP/1.0\r\n", $url['path'], $url['query'] ? "?" : "", $url['query']); 66 | $tmp .= "Host: $url[host]\r\n"; 67 | $tmp .= "Content-type: application/x-www-form-urlencoded\r\n"; 68 | $tmp .= "Content-Length: " . strlen($encoded) . "\r\n"; 69 | $tmp .= "Connection: close\r\n\r\n"; 70 | $tmp .= "$encoded\r\n"; 71 | fputs($fp, $tmp); 72 | 73 | $line = fgets($fp, 1024); 74 | 75 | if (!preg_match("#^HTTP/1\.. 200#i", $line)) 76 | { 77 | $logstr = "MSG" . $line; 78 | return array("FLAG" => 0, "MSG" => $line); 79 | } 80 | 81 | $results = ""; 82 | $inheader = 1; 83 | while (!feof($fp)) 84 | { 85 | $line = fgets($fp, 1024); 86 | if ($inheader && ($line == "\n" || $line == "\r\n")) 87 | { 88 | $inheader = 0; 89 | } 90 | elseif (!$inheader) 91 | { 92 | $results .= $line; 93 | } 94 | } 95 | fclose($fp); 96 | return array("FLAG" => 1, "MSG" => $results); 97 | } 98 | 99 | //MD5方式签名 100 | static function MD5sign($okey, $odata) 101 | { 102 | $signdata = static::hmac("", $odata); 103 | return static::hmac($okey, $signdata); 104 | } 105 | 106 | static function hmac($key, $data) 107 | { 108 | $key = iconv('gb2312', 'utf-8', $key); 109 | $data = iconv('gb2312', 'utf-8', $data); 110 | $b = 64; 111 | if (strlen($key) > $b) 112 | { 113 | $key = pack("H*", md5($key)); 114 | } 115 | $key = str_pad($key, $b, chr(0x00)); 116 | $ipad = str_pad('', $b, chr(0x36)); 117 | $opad = str_pad('', $b, chr(0x5c)); 118 | $k_ipad = $key ^ $ipad; 119 | $k_opad = $key ^ $opad; 120 | return md5($k_opad . pack("H*", md5($k_ipad . $data))); 121 | } 122 | 123 | /* 124 | 功能 把http请求返回数组 格式化成数组 125 | */ 126 | static function parseRecv($source) 127 | { 128 | $ret = array(); 129 | $temp = explode("&", $source); 130 | 131 | foreach ($temp as $value) 132 | { 133 | $index = strpos($value, "="); 134 | $_key = substr($value, 0, $index); 135 | $_value = substr($value, $index + 1); 136 | $ret[$_key] = $_value; 137 | } 138 | 139 | return $ret; 140 | } 141 | 142 | /* 143 | 功能:把UTF-8 编号数据转换成 GB2312 忽略转换错误 144 | */ 145 | static function decodeUtf8($source) 146 | { 147 | $temp = urldecode($source); 148 | $ret = iconv("UTF-8", "GB2312//IGNORE", $temp); 149 | return $ret; 150 | } 151 | 152 | /*获取用户IP地址*/ 153 | static function getClientIP() 154 | { 155 | if (!empty($_SERVER["HTTP_CLIENT_IP"])) 156 | { 157 | $cip = $_SERVER["HTTP_CLIENT_IP"]; 158 | } 159 | else if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) 160 | { 161 | $cip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 162 | } 163 | else if (!empty($_SERVER["REMOTE_ADDR"])) 164 | { 165 | $cip = $_SERVER["REMOTE_ADDR"]; 166 | } 167 | else 168 | { 169 | $cip = "unknown"; 170 | } 171 | return $cip; 172 | 173 | } 174 | 175 | //返回URL处理 176 | static function parseUrl($payUrl) 177 | { 178 | $temp = explode("", $payUrl); 179 | $url_lst = explode("", $temp[0]); 180 | $url = $url_lst[1]; 181 | $method_lst = explode("", $temp[1]); 182 | $method = $method_lst[1]; 183 | $sessionid_lst = explode("", $temp[2]); 184 | $sessionid = $sessionid_lst[1]; 185 | $url = $url . "?SESSIONID=" . $sessionid; 186 | $rpayUrl = array(); 187 | $rpayUrl["url"] = $url; 188 | $rpayUrl["method"] = $method; 189 | return $rpayUrl; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /demo/index.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 支付网关测试 8 | 9 | 15 | 16 | 17 |

支付宝支付测试

18 |
19 |
20 | 25 |

26 | 30 |

31 | 35 | 36 |

37 | 41 |

42 | 43 |
44 |
45 | 46 |

微信支付测试

47 |
48 |
49 | 54 |

55 | 59 |

60 | 64 | 65 |

66 | 70 |

71 | 78 |

79 | 80 |
81 |
82 | 83 | 84 |

微信退款测试

85 |
86 |
87 | 92 |

93 | 97 |

98 | 102 |

103 | 107 |

108 | 112 |

113 | 117 |

118 | 119 |
120 |
121 | 122 |

百度支付测试

123 |
124 |
125 | 130 |

131 | 135 |

136 | 140 | 141 |

142 | 146 |

147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 |
157 |
158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/Omnipay/Cmpay/Message/ExpressPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 13 | **/ 14 | class ExpressPurchaseRequest extends AbstractRequest { 15 | 16 | protected function getParameter($key) 17 | { 18 | return $this->parameters->get($key, ''); 19 | } 20 | 21 | public function initialize(array $parameters = array()) 22 | { 23 | if (null !== $this->response) 24 | { 25 | throw new \RuntimeException('Request cannot be modified after it has been sent!'); 26 | } 27 | 28 | $this->parameters = new ParameterBag; 29 | foreach ($parameters as $k => $v) 30 | { 31 | $this->parameters->set($k, $v); 32 | } 33 | return $this; 34 | } 35 | 36 | /** 37 | * Get the raw data array for this message. The format of this varies from gateway to 38 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 39 | * 40 | * @return mixed 41 | */ 42 | public function getData() 43 | { 44 | $this->validate( 45 | 'app_id', 46 | 'app_key', 47 | 'character_set', 48 | 'sign_type', 49 | 'type', 50 | 'version', 51 | 'out_trade_no', 52 | 'subject', 53 | 'total_fee' 54 | ); 55 | $signKey = $this->getParameter('app_key'); 56 | 57 | $characterSet = $this->getParameter('character_set'); 58 | $callbackUrl = $this->getParameter('return_url'); 59 | $notifyUrl = $this->getParameter('notify_url'); 60 | $ipAddress = $this->getParameter('client_ip'); 61 | $merchantId = $this->getParameter('app_id'); 62 | $requestId = $this->getParameter('request_id') ?: $this->getParameter('out_trade_no'); 63 | $signType = $this->getParameter('sign_type'); 64 | $type = $this->getParameter('type'); 65 | $version = $this->getParameter('version'); 66 | $amount = $this->getParameter('total_fee') * 100; 67 | $bankAbbr = $this->getParameter('bank'); 68 | $currency = '00'; 69 | $orderDate = date('Ymd'); 70 | $orderId = $this->getParameter('out_trade_no'); 71 | $merAcDate = date('Ymd'); 72 | $period = $this->getParameter('expired_time') ?: 10; 73 | $periodUnit = '00'; 74 | $merchantAbbr = $this->getParameter('merchant_abbr'); 75 | $productId = $this->getParameter('product_id') ?: $this->getParameter('out_trade_no'); 76 | $productName = iconv('utf-8', 'gb2312', $this->getParameter('subject')); 77 | $productDesc = iconv('utf-8', 'gb2312', $this->getParameter('summary')); 78 | // $productName = $this->getParameter('subject'); 79 | // $productDesc = $this->getParameter('summary'); 80 | $productNum = 1; 81 | $reserved1 = ''; 82 | $reserved2 = ''; 83 | $userToken = ''; 84 | $showUrl = ''; 85 | $couponsFlag = ''; 86 | 87 | $signData = $characterSet . $callbackUrl . $notifyUrl . $ipAddress 88 | . $merchantId . $requestId . $signType . $type 89 | . $version . $amount . $bankAbbr . $currency 90 | . $orderDate . $orderId . $merAcDate . $period . $periodUnit 91 | . $merchantAbbr . $productDesc . $productId . $productName 92 | . $productNum . $reserved1 . $reserved2 . $userToken 93 | . $showUrl . $couponsFlag; 94 | 95 | $hmac = Utils::MD5sign($signKey, $signData); 96 | 97 | $requestData = array(); 98 | $requestData["characterSet"] = $characterSet; 99 | $requestData["callbackUrl"] = $callbackUrl; 100 | $requestData["notifyUrl"] = $notifyUrl; 101 | $requestData["ipAddress"] = $ipAddress; 102 | $requestData["merchantId"] = $merchantId; 103 | $requestData["requestId"] = $requestId; 104 | $requestData["signType"] = $signType; 105 | $requestData["type"] = $type; 106 | $requestData["version"] = $version; 107 | $requestData["hmac"] = $hmac; 108 | $requestData["amount"] = $amount; 109 | $requestData["bankAbbr"] = $bankAbbr; 110 | $requestData["currency"] = $currency; 111 | $requestData["orderDate"] = $orderDate; 112 | $requestData["orderId"] = $orderId; 113 | $requestData["merAcDate"] = $merAcDate; 114 | $requestData["period"] = $period; 115 | $requestData["periodUnit"] = $periodUnit; 116 | $requestData["merchantAbbr"] = $merchantAbbr; 117 | $requestData["productDesc"] = $productDesc; 118 | $requestData["productId"] = $productId; 119 | $requestData["productName"] = $productName; 120 | $requestData["productNum"] = $productNum; 121 | $requestData["reserved1"] = $reserved1; 122 | $requestData["reserved2"] = $reserved2; 123 | $requestData["userToken"] = $userToken; 124 | $requestData["showUrl"] = $showUrl; 125 | $requestData["couponsFlag"] = $couponsFlag; 126 | $requestData['merchantKey'] = $signKey; 127 | 128 | 129 | 130 | return $requestData; 131 | } 132 | 133 | /** 134 | * Send the request with specified data 135 | * 136 | * @param mixed $data The data to send 137 | * @return ResponseInterface 138 | */ 139 | public function sendData($data) 140 | { 141 | $this->response = new ExpressPurchaseResponse($this, $data); 142 | // if ($this->parameters->has('return_url')) 143 | // { 144 | // $this->response->setReturnUrl($this->parameters->get('return_url')); 145 | // } 146 | return $this->response; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatPurchaseResponse.php: -------------------------------------------------------------------------------- 1 | 13 | **/ 14 | class WechatPurchaseResponse extends BaseAbstractResponse implements RedirectResponseInterface { 15 | 16 | protected $endpoint = 'weixin://wxpay/bizpayurl'; 17 | 18 | /** 19 | * @var bool|string 20 | */ 21 | protected $return_url = false; 22 | 23 | protected $cancel_url = false; 24 | 25 | protected $fail_url = false; 26 | 27 | public function isRedirect() 28 | { 29 | return true; 30 | } 31 | 32 | 33 | /** 34 | * Is the response successful? 35 | * 36 | * @return boolean 37 | */ 38 | public function isSuccessful() 39 | { 40 | return false; 41 | } 42 | 43 | /** 44 | * Gets the redirect target url. 45 | */ 46 | public function getRedirectUrl() 47 | { 48 | $params = $this->getData(); 49 | $key = $params['appkey']; 50 | $params = array_except($params, 'appkey'); 51 | if(!empty($params['productid'])) 52 | { 53 | $params['product_id'] = $params['productid']; 54 | } 55 | $params = array_only($params, ['appid', 'mch_id', 'product_id']); 56 | $params['time_stamp'] = time(); 57 | $params['nonce_str'] = str_random(8); 58 | $sign = CommonUtil::gen_signature($params, $key); 59 | ksort($params); 60 | $url = $this->endpoint . '?sign=' . $sign . '&' . http_build_query($params); 61 | return $url; 62 | } 63 | 64 | /** 65 | * Get the required redirect method (either GET or POST). 66 | */ 67 | public function getRedirectMethod() 68 | { 69 | return 'GET'; 70 | } 71 | 72 | /** 73 | * Gets the redirect form data array, if the redirect method is POST. 74 | */ 75 | public function getRedirectData() 76 | { 77 | $params = array_except($this->getData(), 'productid'); 78 | 79 | $key = $params['appkey']; 80 | 81 | $params = [ 82 | 'appId' => $params['appid'], 83 | 'package' => $params['package'], 84 | 'timeStamp' => '' . $params['timestamp'], 85 | 'nonceStr' => $params['noncestr'], 86 | 'signType' => 'MD5' 87 | ]; 88 | $params['paySign'] = CommonUtil::gen_signature($params, $key); 89 | 90 | return $params; 91 | } 92 | 93 | public function redirect($content_type = 'html') 94 | { 95 | // $agent = strtolower(array_get($_SERVER, 'HTTP_USER_AGENT', '')); 96 | // if(str_contains($agent, 'iphone')){ 97 | // return parent::redirect(); 98 | // } 99 | $data = $this->getRedirectData(); 100 | $return_url = $this->return_url ? : array_get($_SERVER, 'HTTP_REFERER', false); 101 | $refered_url = array_get($_SERVER, 'HTTP_REFERER', $return_url); 102 | $cancel_url = $this->cancel_url ? : $refered_url; 103 | $fail_url = $this->fail_url ?: $refered_url; 104 | 105 | switch ($content_type) 106 | { 107 | case 'html': 108 | $output = $this->redirect_html(); 109 | break; 110 | case 'js': 111 | case 'javascript': 112 | $output = $this->redirect_js(); 113 | break; 114 | default: 115 | $output = $this->redirect_html(); 116 | } 117 | 118 | $output = sprintf($output, json_encode($data), $return_url, $cancel_url, $fail_url); 119 | 120 | return HttpResponse::create($output)->send(); 121 | } 122 | 123 | protected function redirect_html() 124 | { 125 | return ' 126 | 127 | 128 | 129 | 微信安全支付 130 | 131 | 132 |

付款中...

133 | 134 | 137 | '; 138 | } 139 | 140 | protected function redirect_js() 141 | { 142 | return '(function(){ 143 | var data = %1$s; 144 | 145 | setTimeout(function(){ 146 | if(typeof WeixinJSBridge == "undefined"){ 147 | return setTimeout(arguments.callee, 200); 148 | } 149 | WeixinJSBridge.invoke( 150 | "getBrandWCPayRequest",data,function(res){ 151 | // 返回 res.err_msg,取值 152 | // get_brand_wcpay_request:cancel 用户取消 153 | // get_brand_wcpay_request:fail 发送失败 154 | // get_brand_wcpay_request:ok 发送成功 155 | if(res.err_msg == "get_brand_wcpay_request:ok"){ 156 | alert("支付成功"); 157 | window.location.href = "%2$s"; 158 | }else if(res.err_msg == "get_brand_wcpay_request:cancel"){ 159 | alert("支付取消"); 160 | window.location.href = "%3$s"; 161 | }else{ 162 | alert("支付失败(" + res["err_msg"] + ")"); 163 | window.location.href = "%4$s"; 164 | } 165 | //WeixinJSBridge.log(res.err_msg); alert(res.err_code+res.err_desc); 166 | }); 167 | 168 | }, 200); 169 | })();'; 170 | } 171 | 172 | public function setReturnUrl($url) 173 | { 174 | $this->return_url = $url; 175 | } 176 | 177 | public function setCancelUrl($url) 178 | { 179 | $this->cancel_url = $url; 180 | } 181 | 182 | public function setFailUrl($url) 183 | { 184 | $this->fail_url = $url; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/WapExpressAuthorizeRequest.php: -------------------------------------------------------------------------------- 1 | validate( 25 | 'notify_url', 26 | 'return_url', 27 | 'seller_email', 28 | 'out_trade_no', 29 | 'subject', 30 | 'total_fee', 31 | 'cancel_url' 32 | ); 33 | $format = '' . /**/ 34 | '%s' . /**/ 35 | '%s' . /**/ 36 | '%s' . /**/ 37 | '%s' . /**/ 38 | '%s' . /**/ 39 | '%s' . /**/ 40 | '%s' . /**/ 41 | ''; 42 | $req_data = sprintf( 43 | $format, 44 | $this->getNotifyUrl(), 45 | $this->getReturnUrl(), 46 | $this->getSellerEmail(), 47 | $this->getOutTradeNo(), 48 | $this->getSubject(), 49 | $this->getTotalFee(), 50 | $this->getCancelUrl() 51 | ); 52 | $data = array( 53 | "service" => "alipay.wap.trade.create.direct", 54 | "partner" => $this->getPartner(), 55 | "sec_id" => $this->getSignType(), 56 | "format" => 'xml', 57 | "v" => '2.0', 58 | "req_id" => microtime(true) . '', 59 | "req_data" => $req_data, 60 | "_input_charset" => $this->getInputCharset() 61 | ); 62 | $data['sign'] = $this->getParamsSignature($data); 63 | return $data; 64 | } 65 | 66 | public function getKey() 67 | { 68 | return $this->getParameter('key'); 69 | } 70 | 71 | public function setKey($value) 72 | { 73 | return $this->setParameter('key', $value); 74 | } 75 | 76 | public function getInputCharset() 77 | { 78 | return $this->getParameter('input_charset'); 79 | } 80 | 81 | public function setInputCharset($value) 82 | { 83 | return $this->setParameter('input_charset', $value); 84 | } 85 | 86 | public function getSignType() 87 | { 88 | return $this->getParameter('sign_type'); 89 | } 90 | 91 | public function setSignType($value) 92 | { 93 | return $this->setParameter('sign_type', $value); 94 | } 95 | 96 | public function getPartner() 97 | { 98 | return $this->getParameter('partner'); 99 | } 100 | 101 | public function setPartner($value) 102 | { 103 | return $this->setParameter('partner', $value); 104 | } 105 | 106 | public function getTotalFee() 107 | { 108 | return $this->getParameter('total_fee'); 109 | } 110 | 111 | public function setTotalFee($value) 112 | { 113 | return $this->setParameter('total_fee', $value); 114 | } 115 | 116 | public function getSubject() 117 | { 118 | return $this->getParameter('subject'); 119 | } 120 | 121 | public function setSubject($value) 122 | { 123 | return $this->setParameter('subject', $value); 124 | } 125 | 126 | public function getOutTradeNo() 127 | { 128 | return $this->getParameter('out_trade_no'); 129 | } 130 | 131 | public function setOutTradeNo($value) 132 | { 133 | return $this->setParameter('out_trade_no', $value); 134 | } 135 | 136 | public function getSellerEmail() 137 | { 138 | return $this->getParameter('seller_email'); 139 | } 140 | 141 | public function setSellerEmail($value) 142 | { 143 | return $this->setParameter('seller_email', $value); 144 | } 145 | 146 | public function getNotifyUrl() 147 | { 148 | return $this->getParameter('notify_url'); 149 | } 150 | 151 | public function setNotifyUrl($value) 152 | { 153 | return $this->setParameter('notify_url', $value); 154 | } 155 | 156 | public function getReturnUrl() 157 | { 158 | return $this->getParameter('return_url'); 159 | } 160 | 161 | public function setReturnUrl($value) 162 | { 163 | return $this->setParameter('return_url', $value); 164 | } 165 | 166 | public function getCancelUrl() 167 | { 168 | return $this->getParameter('cancel_url'); 169 | } 170 | 171 | public function setCancelUrl($value) 172 | { 173 | return $this->setParameter('cancel_url', $value); 174 | } 175 | 176 | public function sendData($data) 177 | { 178 | $responseText = $this->httpClient->post($this->endpoint, array(), $this->getData()) /**/ 179 | ->send()->getBody(true); 180 | //die($responseText); 181 | $responseData = $this->parseResponse($responseText); 182 | //var_dump($responseData); 183 | return $this->response = new WapExpressAuthorizeResponse($this, $responseData); 184 | } 185 | 186 | public function parseResponse($str_text) 187 | { 188 | $str_text = urldecode($str_text); //URL转码 189 | $para_split = explode('&', $str_text); 190 | $data = array(); 191 | foreach ($para_split as $item) { 192 | $nPos = strpos($item, '='); 193 | $nLen = strlen($item); 194 | $key = substr($item, 0, $nPos); 195 | $value = substr($item, $nPos + 1, $nLen - $nPos - 1); 196 | $data[$key] = $value; 197 | } 198 | if (!empty ($data['res_data'])) { 199 | if ($this->getSignType() == '0001') { 200 | $data['res_data'] = rsaDecrypt($data['res_data'], $this->getPrivateKey()); 201 | } 202 | $doc = new DOMDocument(); 203 | $doc->loadXML($data['res_data']); 204 | $data['request_token'] = $doc->getElementsByTagName("request_token")->item(0)->nodeValue; 205 | } 206 | return $data; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Message/WechatCompletePurchaseRequest.php: -------------------------------------------------------------------------------- 1 | 11 | **/ 12 | class WechatCompletePurchaseRequest extends BaseAbstractRequest { 13 | 14 | 15 | function setAppId($appId) 16 | { 17 | $this->setParameter('app_id', $appId); 18 | } 19 | 20 | function getAppId() 21 | { 22 | return $this->getParameter('app_id'); 23 | } 24 | 25 | function setAppKey($key) 26 | { 27 | $this->setParameter('app_key', $key); 28 | } 29 | 30 | function getAppKey() 31 | { 32 | return $this->getParameter('app_key'); 33 | } 34 | 35 | 36 | function getPartner() 37 | { 38 | return $this->getParameter('partner'); 39 | } 40 | 41 | function setPartner($id) 42 | { 43 | $this->setParameter('partner', $id); 44 | } 45 | 46 | function getPartnerKey() 47 | { 48 | return $this->getParameter('partner_key'); 49 | } 50 | 51 | function setPartnerKey($key) 52 | { 53 | $this->setParameter('partner_key', $key); 54 | } 55 | 56 | function getBody() 57 | { 58 | return $this->getParameter('body', array()); 59 | } 60 | 61 | function setBody($body) 62 | { 63 | $this->setParameter('body', $body); 64 | } 65 | 66 | function getRequestParams() 67 | { 68 | $this->getParameter('request_params', array()); 69 | } 70 | 71 | function setRequestParams($rp) 72 | { 73 | $this->setParameter('request_params', $rp); 74 | } 75 | 76 | /** 77 | * Get the raw data array for this message. The format of this varies from gateway to 78 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 79 | * 80 | * @return mixed 81 | */ 82 | public function getData() 83 | { 84 | $this->validate( 85 | 'body' 86 | ); 87 | return $this->getParameters(); 88 | } 89 | 90 | /** 91 | * Send the request with specified data 92 | * 93 | * @param mixed $data The data to send 94 | * @return ResponseInterface 95 | */ 96 | public function sendData($data) 97 | { 98 | $body = $data['body']; 99 | $notify = new Notify(); 100 | $notify->init(array( 101 | 'app_id' => $data['app_id'], 102 | 'mch_id' => $data['partner'], 103 | 'app_secret' => '', 104 | 'pay_sign_key' => $data['app_key'], 105 | 'cert_path' => '', 106 | 'cert_key_path' => '', 107 | )); 108 | $notify->saveData($body); 109 | 110 | if ($notify->checkSign() == FALSE) 111 | { 112 | $notify->setReturnParameter('return_code', 'FAIL'); 113 | $notify->setReturnParameter('return_msg', '签名失败'); 114 | } 115 | else 116 | { 117 | $notify->setReturnParameter('return_code', 'SUCCESS'); 118 | } 119 | $returnXml = $notify->returnXml(); 120 | 121 | $res_data['status'] = $notify->checkSign(); 122 | $res_data['return_msg'] = $returnXml; 123 | $res_data['trade_status_ok'] = $notify->checkSign(); 124 | 125 | return $this->response = new WechatCompletePurchaseResponse($this, $res_data); 126 | } 127 | 128 | /** 129 | * sort the query string 130 | * @param $qstr 131 | * @return array 132 | */ 133 | static function sort($qstr) 134 | { 135 | $queryParts = explode('&', $qstr); 136 | 137 | $params = array(); 138 | foreach ($queryParts as $param) 139 | { 140 | $item = explode('=', $param); 141 | $params [$item [0]] = $item [1]; 142 | } 143 | ksort($params); 144 | return $params; 145 | } 146 | 147 | /** 148 | * like http_build_query(), but skip null value and do job after ksort 149 | * 150 | * @param $params 151 | * @return string 152 | * 153 | */ 154 | static function http_build_query_without_null($params) 155 | { 156 | $buff = ""; 157 | ksort($params); 158 | foreach ($params as $k => $v) 159 | { 160 | if (null != $v && "null" != $v && "sign" != $k) 161 | { 162 | $buff .= $k . "=" . $v . "&"; 163 | } 164 | } 165 | $reqPar = ''; 166 | if (strlen($buff) > 0) 167 | { 168 | $reqPar = substr($buff, 0, strlen($buff) - 1); 169 | } 170 | return $reqPar; 171 | } 172 | 173 | /** 174 | * like http_build_query(), ext: url encode the value and do job after ksort 175 | * @param $paraMap 176 | * @param $urlencode 177 | * @return string 178 | */ 179 | static function formatBizQuery($paraMap, $urlencode) 180 | { 181 | $buff = ""; 182 | ksort($paraMap); 183 | foreach ($paraMap as $k => $v) 184 | { 185 | if ($urlencode) 186 | { 187 | $v = urlencode($v); 188 | } 189 | $buff .= strtolower($k) . "=" . $v . "&"; 190 | } 191 | $reqPar = ''; 192 | if (strlen($buff) > 0) 193 | { 194 | $reqPar = substr($buff, 0, strlen($buff) - 1); 195 | } 196 | return $reqPar; 197 | } 198 | 199 | /** 200 | * sign with app_key 201 | * @param $params 202 | * @return string 203 | */ 204 | protected function bizSign($params) 205 | { 206 | foreach ($params as $k => $v) 207 | { 208 | $bizParameters [strtolower($k)] = $v; 209 | } 210 | 211 | $bizParameters["appkey"] = $this->getAppKey(); 212 | ksort($bizParameters); 213 | $bizString = static::formatBizQuery($bizParameters, false); 214 | return sha1($bizString); 215 | } 216 | 217 | /** 218 | * 检查signature是否一致 219 | * @param $body 220 | * @param $signature 221 | * @return bool 222 | */ 223 | protected function verifyBody($body, $signature) 224 | { 225 | return $body && $signature && $signature == $this->bizSign($body); 226 | } 227 | 228 | /** 229 | * signature check, the params sign with partner key 230 | * @param $params 231 | * @return bool 232 | */ 233 | protected function verifyParam($params) 234 | { 235 | $signStr = static::http_build_query_without_null($params); 236 | $stringSignTemp = $signStr . '&key=' . $this->getPartnerKey(); 237 | $signValue = strtoupper(md5($stringSignTemp)); 238 | 239 | return !empty($params['sign']) && $signValue == $params['sign']; 240 | } 241 | } -------------------------------------------------------------------------------- /src/Omnipay/Alipay/Message/MobileExpressPurchaseRequest.php: -------------------------------------------------------------------------------- 1 | validate( 19 | 'partner', 20 | 'out_trade_no', 21 | 'subject', 22 | 'total_fee', 23 | 'notify_url', 24 | 'show_url', 25 | 'return_url', 26 | 'private_key' 27 | ); 28 | } 29 | 30 | /** 31 | * Get the raw data array for this message. The format of this varies from gateway to 32 | * gateway, but will usually be either an associative array, or a SimpleXMLElement. 33 | * 34 | * @return mixed 35 | */ 36 | public function getData() 37 | { 38 | $this->validateData(); 39 | $data = array( 40 | 'partner' => $this->getPartner(), 41 | 'seller_id' => $this->getPartner(), 42 | 'out_trade_no' => $this->getOutTradeNo(), 43 | 'subject' => $this->getSubject(), 44 | 'body' => $this->getBody(), 45 | 'total_fee' => $this->getTotalFee(), 46 | 'notify_url' => $this->getNotifyUrl(), 47 | 'service' => $this->service, 48 | '_input_charset' => 'utf-8', 49 | 'payment_type' => '1', 50 | 'it_b_pay' => $this->getItBPay(), 51 | 'show_url' => $this->getShowUrl(), 52 | 'return_url' => $this->getReturnUrl(), 53 | ); 54 | $data = array_filter($data); 55 | $data['sign'] = $this->getParamsSignature($data); 56 | $data['sign_type'] = $this->getSignType(); 57 | $orderInfoStr = http_build_query($data); 58 | $orderInfoStr = str_replace('&', '"&', $orderInfoStr); 59 | $orderInfoStr = str_replace('=', '="', $orderInfoStr) . '"'; 60 | $rsa_sign = $this->rsaSign($orderInfoStr, $this->getPrivateKey()); 61 | $resp['order_info_str'] = sprintf('%s&sign="%s"&sign_type="%s"', $orderInfoStr, urlencode($rsa_sign), 'RSA'); 62 | return $resp; 63 | } 64 | 65 | public function rsaSign($data, $private_key) 66 | { 67 | $res = openssl_pkey_get_private($private_key); 68 | openssl_sign($data, $sign, $res); 69 | openssl_free_key($res); 70 | $sign = base64_encode($sign); 71 | return $sign; 72 | } 73 | 74 | public function getPrivateKey() 75 | { 76 | return $this->getParameter('private_key'); 77 | } 78 | 79 | public function setPrivateKey($value) 80 | { 81 | $this->setParameter('private_key', $value); 82 | } 83 | 84 | public function getItBPay() 85 | { 86 | return $this->getParameter('it_b_pay'); 87 | } 88 | 89 | public function setItBPay($value) 90 | { 91 | $this->setParameter('it_b_pay', $value); 92 | } 93 | 94 | public function getTotalFee() 95 | { 96 | return $this->getParameter('total_fee'); 97 | } 98 | 99 | public function setTotalFee($value) 100 | { 101 | $this->setParameter('total_fee', $value); 102 | } 103 | 104 | public function getService() 105 | { 106 | return $this->getParameter('service'); 107 | } 108 | 109 | public function setService($value) 110 | { 111 | $this->setParameter('service', $value); 112 | } 113 | 114 | public function getOutTradeNo() 115 | { 116 | return $this->getParameter('out_trade_no'); 117 | } 118 | 119 | public function setOutTradeNo($value) 120 | { 121 | $this->setParameter('out_trade_no', $value); 122 | } 123 | 124 | public function getTransport() 125 | { 126 | return $this->getParameter('transport'); 127 | } 128 | 129 | public function setTransport($value) 130 | { 131 | $this->setParameter('transport', $value); 132 | } 133 | 134 | public function getAntiPhishingKey() 135 | { 136 | return $this->getParameter('anti_phishing_key'); 137 | } 138 | 139 | public function setAntiPhishingKey($value) 140 | { 141 | $this->setParameter('anti_phishing_key', $value); 142 | } 143 | 144 | public function getExterInvokeIp() 145 | { 146 | return $this->getParameter('exter_invoke_ip'); 147 | } 148 | 149 | public function setExterInvokeIp($value) 150 | { 151 | $this->setParameter('exter_invoke_ip', $value); 152 | } 153 | 154 | public function getBody() 155 | { 156 | return $this->getParameter('body'); 157 | } 158 | 159 | public function setBody($value) 160 | { 161 | $this->setParameter('body', $value); 162 | } 163 | 164 | public function getPartner() 165 | { 166 | return $this->getParameter('partner'); 167 | } 168 | 169 | public function setPartner($value) 170 | { 171 | $this->setParameter('partner', $value); 172 | } 173 | 174 | public function getShowUrl() 175 | { 176 | return $this->getParameter('show_url'); 177 | } 178 | 179 | public function setShowUrl($value) 180 | { 181 | $this->setParameter('show_url', $value); 182 | } 183 | 184 | public function getInputCharset() 185 | { 186 | return $this->getParameter('input_charset'); 187 | } 188 | 189 | public function setInputCharset($value) 190 | { 191 | $this->setParameter('input_charset', $value); 192 | } 193 | 194 | public function getKey() 195 | { 196 | return $this->getParameter('key'); 197 | } 198 | 199 | public function setKey($value) 200 | { 201 | $this->setParameter('key', $value); 202 | } 203 | 204 | public function getNotifyUrl() 205 | { 206 | return $this->getParameter('notify_url'); 207 | } 208 | 209 | public function setNotifyUrl($value) 210 | { 211 | $this->setParameter('notify_url', $value); 212 | } 213 | 214 | public function getReturnUrl() 215 | { 216 | return $this->getParameter('return_url'); 217 | } 218 | 219 | public function setReturnUrl($value) 220 | { 221 | $this->setParameter('return_url', $value); 222 | } 223 | 224 | public function getSignType() 225 | { 226 | return $this->getParameter('sign_type'); 227 | } 228 | 229 | public function setSignType($value) 230 | { 231 | $this->setParameter('sign_type', $value); 232 | } 233 | 234 | public function getSubject() 235 | { 236 | return $this->getParameter('subject'); 237 | } 238 | 239 | public function setSubject($value) 240 | { 241 | $this->setParameter('subject', $value); 242 | } 243 | 244 | /** 245 | * Send the request with specified data 246 | * 247 | * @param mixed $data The data to send 248 | * 249 | * @return ResponseInterface 250 | */ 251 | public function sendData($data) 252 | { 253 | return $this->response = new MobileExpressPurchaseResponse($this, $data); 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /demo/js/json_to_table.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JavaScript format string function 3 | * 4 | */ 5 | String.prototype.format = function() 6 | { 7 | var args = arguments; 8 | 9 | return this.replace(/{(\d+)}/g, function(match, number) 10 | { 11 | return typeof args[number] != 'undefined' ? args[number] : 12 | '{' + number + '}'; 13 | }); 14 | }; 15 | 16 | 17 | /** 18 | * Convert a Javascript Oject array or String array to an HTML table 19 | * JSON parsing has to be made before function call 20 | * It allows use of other JSON parsing methods like jQuery.parseJSON 21 | * http(s)://, ftp://, file:// and javascript:; links are automatically computed 22 | * 23 | * JSON data samples that should be parsed and then can be converted to an HTML table 24 | * var objectArray = '[{"Total":"34","Version":"1.0.4","Office":"New York"},{"Total":"67","Version":"1.1.0","Office":"Paris"}]'; 25 | * var stringArray = '["New York","Berlin","Paris","Marrakech","Moscow"]'; 26 | * var nestedTable = '[{ key1: "val1", key2: "val2", key3: { tableId: "tblIdNested1", tableClassName: "clsNested", linkText: "Download", data: [{ subkey1: "subval1", subkey2: "subval2", subkey3: "subval3" }] } }]'; 27 | * 28 | * Code sample to create a HTML table Javascript String 29 | * var jsonHtmlTable = ConvertJsonToTable(eval(dataString), 'jsonTable', null, 'Download'); 30 | * 31 | * Code sample explaned 32 | * - eval is used to parse a JSON dataString 33 | * - table HTML id attribute will be 'jsonTable' 34 | * - table HTML class attribute will not be added 35 | * - 'Download' text will be displayed instead of the link itself 36 | * 37 | * @author Afshin Mehrabani 38 | * 39 | * @class ConvertJsonToTable 40 | * 41 | * @method ConvertJsonToTable 42 | * 43 | * @param parsedJson object Parsed JSON data 44 | * @param tableId string Optional table id 45 | * @param tableClassName string Optional table css class name 46 | * @param linkText string Optional text replacement for link pattern 47 | * 48 | * @return string Converted JSON to HTML table 49 | */ 50 | function ConvertJsonToTable(parsedJson, tableId, tableClassName, linkText) 51 | { 52 | //Patterns for links and NULL value 53 | var italic = '{0}'; 54 | var link = linkText ? '' + linkText + '' : 55 | '{0}'; 56 | 57 | //Pattern for table 58 | var idMarkup = tableId ? ' id="' + tableId + '"' : 59 | ''; 60 | 61 | var classMarkup = tableClassName ? ' class="' + tableClassName + '"' : 62 | ''; 63 | 64 | var tbl = '{0}{1}
'; 65 | 66 | //Patterns for table content 67 | var th = '{0}'; 68 | var tb = '{0}'; 69 | var tr = '{0}'; 70 | var thRow = '{0}'; 71 | var tdRow = '{0}'; 72 | var thCon = ''; 73 | var tbCon = ''; 74 | var trCon = ''; 75 | 76 | if (parsedJson) 77 | { 78 | var isStringArray = typeof(parsedJson[0]) == 'string'; 79 | var headers; 80 | 81 | // Create table headers from JSON data 82 | // If JSON data is a simple string array we create a single table header 83 | if(isStringArray) 84 | thCon += thRow.format('value'); 85 | else 86 | { 87 | // If JSON data is an object array, headers are automatically computed 88 | if(typeof(parsedJson[0]) == 'object') 89 | { 90 | headers = array_keys(parsedJson[0]); 91 | 92 | for (i = 0; i < headers.length; i++) 93 | thCon += thRow.format(headers[i]); 94 | } 95 | } 96 | th = th.format(tr.format(thCon)); 97 | 98 | // Create table rows from Json data 99 | if(isStringArray) 100 | { 101 | for (i = 0; i < parsedJson.length; i++) 102 | { 103 | tbCon += tdRow.format(parsedJson[i]); 104 | trCon += tr.format(tbCon); 105 | tbCon = ''; 106 | } 107 | } 108 | else 109 | { 110 | if(headers) 111 | { 112 | var urlRegExp = new RegExp(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig); 113 | var javascriptRegExp = new RegExp(/(^javascript:[\s\S]*;$)/ig); 114 | 115 | for (i = 0; i < parsedJson.length; i++) 116 | { 117 | for (j = 0; j < headers.length; j++) 118 | { 119 | var value = parsedJson[i][headers[j]]; 120 | var isUrl = urlRegExp.test(value) || javascriptRegExp.test(value); 121 | 122 | if(isUrl) // If value is URL we auto-create a link 123 | tbCon += tdRow.format(link.format(value)); 124 | else 125 | { 126 | if(value){ 127 | if(typeof(value) == 'object'){ 128 | //for supporting nested tables 129 | tbCon += tdRow.format(ConvertJsonToTable(eval(value.data), value.tableId, value.tableClassName, value.linkText)); 130 | } else { 131 | tbCon += tdRow.format(value); 132 | } 133 | 134 | } else { // If value == null we format it like PhpMyAdmin NULL values 135 | tbCon += tdRow.format(italic.format(value).toUpperCase()); 136 | } 137 | } 138 | } 139 | trCon += tr.format(tbCon); 140 | tbCon = ''; 141 | } 142 | } 143 | } 144 | tb = tb.format(trCon); 145 | tbl = tbl.format(th, tb); 146 | 147 | return tbl; 148 | } 149 | return null; 150 | } 151 | 152 | 153 | /** 154 | * Return just the keys from the input array, optionally only for the specified search_value 155 | * version: 1109.2015 156 | * discuss at: http://phpjs.org/functions/array_keys 157 | * + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 158 | * + input by: Brett Zamir (http://brett-zamir.me) 159 | * + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 160 | * + improved by: jd 161 | * + improved by: Brett Zamir (http://brett-zamir.me) 162 | * + input by: P 163 | * + bugfixed by: Brett Zamir (http://brett-zamir.me) 164 | * * example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} ); 165 | * * returns 1: {0: 'firstname', 1: 'surname'} 166 | */ 167 | function array_keys(input, search_value, argStrict) 168 | { 169 | var search = typeof search_value !== 'undefined', tmp_arr = [], strict = !!argStrict, include = true, key = ''; 170 | 171 | if (input && typeof input === 'object' && input.change_key_case) { // Duck-type check for our own array()-created PHPJS_Array 172 | return input.keys(search_value, argStrict); 173 | } 174 | 175 | for (key in input) 176 | { 177 | if (input.hasOwnProperty(key)) 178 | { 179 | include = true; 180 | if (search) 181 | { 182 | if (strict && input[key] !== search_value) 183 | include = false; 184 | else if (input[key] != search_value) 185 | include = false; 186 | } 187 | if (include) 188 | tmp_arr[tmp_arr.length] = key; 189 | } 190 | } 191 | return tmp_arr; 192 | } -------------------------------------------------------------------------------- /src/Omnipay/Wechat/Sdk/CommonUtil.php: -------------------------------------------------------------------------------- 1 | 8 | **/ 9 | class CommonUtil { 10 | 11 | protected $app_id = ''; 12 | protected $app_secret = ''; 13 | protected $pay_sign_key = ''; 14 | protected $mch_id = ''; 15 | protected $cert_path = ''; 16 | protected $cert_key_path = ''; 17 | protected $pub_cert_path = ''; 18 | 19 | function init($opts) 20 | { 21 | $this->app_id = $opts['app_id']; 22 | $this->app_secret = $opts['app_secret']; 23 | $this->mch_id = array_get($opts, 'mch_id', ''); 24 | $this->pay_sign_key = array_get($opts, 'pay_sign_key', ''); 25 | $this->cert_path = array_get($opts, 'cert_path', ''); 26 | $this->cert_key_path = array_get($opts, 'cert_key_path', ''); 27 | $this->pub_cert_path = array_get($opts, 'pub_cert_path', ''); 28 | return $this; 29 | } 30 | 31 | const CURL_TIMEOUT = 30; 32 | 33 | function __construct() 34 | { 35 | } 36 | 37 | function trimString($value) 38 | { 39 | $ret = null; 40 | if (null != $value) 41 | { 42 | $ret = $value; 43 | if (strlen($ret) == 0) 44 | { 45 | $ret = null; 46 | } 47 | } 48 | return $ret; 49 | } 50 | 51 | /** 52 | * 作用:产生随机字符串,不长于32位 53 | */ 54 | public function createNoncestr($length = 32) 55 | { 56 | $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; 57 | $str = ""; 58 | for ($i = 0; $i < $length; $i++) 59 | { 60 | $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 61 | } 62 | return $str; 63 | } 64 | 65 | /** 66 | * 作用:格式化参数,签名过程需要使用 67 | */ 68 | function formatBizQueryParaMap($paraMap, $urlencode) 69 | { 70 | return static::_formatBizQueryParaMap($paraMap, $urlencode); 71 | } 72 | 73 | static public function _formatBizQueryParaMap($paraMap, $urlencode) 74 | { 75 | $buff = ""; 76 | ksort($paraMap); 77 | foreach ($paraMap as $k => $v) 78 | { 79 | if ($urlencode) 80 | { 81 | $v = urlencode($v); 82 | } 83 | //$buff .= strtolower($k) . "=" . $v . "&"; 84 | $buff .= $k . "=" . $v . "&"; 85 | } 86 | $reqPar = ''; 87 | if (strlen($buff) > 0) 88 | { 89 | $reqPar = substr($buff, 0, strlen($buff) - 1); 90 | } 91 | return $reqPar; 92 | } 93 | 94 | static public function gen_signature($obj, $key) 95 | { 96 | foreach ($obj as $k => $v) 97 | { 98 | $Parameters[$k] = $v; 99 | } 100 | //签名步骤一:按字典序排序参数 101 | ksort($Parameters); 102 | $String = static::_formatBizQueryParaMap($Parameters, false); 103 | //echo '【string1】'.$String.'
'; 104 | //签名步骤二:在string后加入KEY 105 | $String = $String . "&key=" . $key; 106 | //echo "【string2】".$String."
"; 107 | //签名步骤三:MD5加密 108 | $String = md5($String); 109 | //echo "【string3】 ".$String."
"; 110 | //签名步骤四:所有字符转为大写 111 | $result_ = strtoupper($String); 112 | //echo "【result】 ".$result_."
"; 113 | return $result_; 114 | } 115 | 116 | /** 117 | * 作用:生成签名 118 | */ 119 | public function getSign($Obj) 120 | { 121 | return static::gen_signature($Obj, $this->pay_sign_key); 122 | } 123 | 124 | /** 125 | * 作用:array转xml 126 | */ 127 | function arrayToXml($arr) 128 | { 129 | $xml = ""; 130 | foreach ($arr as $key => $val) 131 | { 132 | if (is_numeric($val)) 133 | { 134 | $xml .= "<" . $key . ">" . $val . ""; 135 | 136 | } 137 | else 138 | $xml .= "<" . $key . ">"; 139 | } 140 | $xml .= ""; 141 | return $xml; 142 | } 143 | 144 | /** 145 | * 作用:将xml转为array 146 | */ 147 | public function xmlToArray($xml) 148 | { 149 | //将XML转为array 150 | $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 151 | return $array_data; 152 | } 153 | 154 | /** 155 | * 作用:以post方式提交xml到对应的接口url 156 | */ 157 | public function postXmlCurl($xml, $url, $second = 30) 158 | { 159 | //初始化curl 160 | $ch = curl_init(); 161 | //设置超时 162 | curl_setopt($ch, CURLOPT_TIMEOUT, $second); 163 | //这里设置代理,如果有的话 164 | //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); 165 | //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); 166 | curl_setopt($ch, CURLOPT_URL, $url); 167 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 168 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 169 | //设置header 170 | # curl_setopt($ch, CURLOPT_HEADER, FALSE); 171 | //要求结果为字符串且输出到屏幕上 172 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 173 | //post提交方式 174 | curl_setopt($ch, CURLOPT_POST, TRUE); 175 | curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 176 | //运行curl 177 | $data = curl_exec($ch); 178 | //curl_close($ch); 179 | //返回结果 180 | if ($data) 181 | { 182 | curl_close($ch); 183 | return $data; 184 | } 185 | else 186 | { 187 | $error = curl_errno($ch); 188 | echo "curl出错,错误码:$error" . "
"; 189 | echo "错误原因查询
"; 190 | curl_close($ch); 191 | return false; 192 | } 193 | } 194 | 195 | /** 196 | * 作用:使用证书,以post方式提交xml到对应的接口url 197 | */ 198 | function postXmlSSLCurl($xml, $url, $second = 30) 199 | { 200 | $ch = curl_init(); 201 | //超时时间 202 | curl_setopt($ch, CURLOPT_TIMEOUT, $second); 203 | //这里设置代理,如果有的话 204 | //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); 205 | //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); 206 | curl_setopt($ch, CURLOPT_URL, $url); 207 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 208 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 209 | //设置header 210 | curl_setopt($ch, CURLOPT_HEADER, FALSE); 211 | //要求结果为字符串且输出到屏幕上 212 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 213 | //设置证书 214 | //使用证书:cert 与 key 分别属于两个.pem文件 215 | //默认格式为PEM,可以注释 216 | curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); 217 | // curl_setopt($ch, CURLOPT_SSLCERT, WxPayConf_pub::SSLCERT_PATH); 218 | curl_setopt($ch, CURLOPT_SSLCERT, $this->cert_path); 219 | //默认格式为PEM,可以注释 220 | curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); 221 | // curl_setopt($ch, CURLOPT_SSLKEY, WxPayConf_pub::SSLKEY_PATH); 222 | curl_setopt($ch, CURLOPT_SSLKEY, $this->cert_key_path); 223 | //post提交方式 224 | curl_setopt($ch, CURLOPT_POST, true); 225 | curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 226 | $data = curl_exec($ch); 227 | //返回结果 228 | if ($data) 229 | { 230 | curl_close($ch); 231 | return $data; 232 | } 233 | else 234 | { 235 | $error = curl_errno($ch); 236 | echo "curl出错,错误码:$error" . "
"; 237 | echo "错误原因查询
"; 238 | curl_close($ch); 239 | return false; 240 | } 241 | } 242 | 243 | /** 244 | * 作用:打印数组 245 | */ 246 | function printErr($wording = '', $err = '') 247 | { 248 | print_r('
');
249 |         echo $wording . "
"; 250 | var_dump($err); 251 | print_r('
'); 252 | } 253 | } 254 | 255 | 256 | 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /demo/alipay.redirect.php.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ~/usr/src/codelint/codelint/collie/branches/dev/client/chinapay/demo/alipay.redirect.php.html 6 | 7 | 8 | 9 | 10 | 11 | 25 | 26 | 31 | 32 | 33 |
34 | <?php
35 | $config = require_once('./config.php');
36 | 
37 | $config = $config['alipay'];
38 | 
39 | /**
40 |  * 支付宝: 跳转到支付界面
41 |  * @param $config
42 |  */
43 | function alipay_redirect($config)
44 | {
45 |     /*
46 |      * @var Omnipay\Alipay\WapExpressGateway
47 |      */
48 |     try
49 |     {
50 |         // $gateway = \Omnipay\Omnipay::create('Alipay_WapExpress')
51 |         $gateway = new \Omnipay\Alipay\WapExpressGateway();
52 |         $gateway->setPartner($config['partner']);
53 |         $gateway->setKey($config['key']);
54 |         $gateway->setSellerEmail($config['seller_email']);
55 |         $gateway->setNotifyUrl($config['notify_url']);
56 |         $gateway->setReturnUrl($config['return_url']);
57 |         $gateway->setCancelUrl($config['cancel_url']);
58 |         $opts = array(
59 |             'subject' => $_GET['subject'],
60 |             'description' => '暂无',
61 |             'total_fee' => $_GET['total_fee'],
62 |             'out_trade_no' => $_GET['out_trade_no'],
63 |         );
64 |         $res = $gateway->purchase($opts)->send();
65 |         $cache = get_cache();
66 |         $cache->save($_GET['out_trade_no'], $opts);
67 |         $res->redirect();
68 | //        header("Content-type: application/json");
69 | //        echo json_encode([
70 | //            'url' => $res->getRedirectUrl(),
71 | //            'opts' => $opts,
72 | //            'config' => $config,
73 | //            'info_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/demo/info.php?out_trade_no=' . $out_trade_no,
74 | //        ]);
75 |     } catch (\Exception $e)
76 |     {
77 |         var_dump($e->getMessage());
78 |     }
79 | }
80 | 
81 | alipay_redirect($config);
82 | 
83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /demo/wechat.redirect.php.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ~/usr/src/codelint/codelint/collie/branches/dev/client/chinapay/demo/wechat.redirect.php.html 6 | 7 | 8 | 9 | 10 | 11 | 25 | 26 | 31 | 32 | 33 |
34 | <?php
35 | /*
36 |  * notice :
37 |  *  return url must not have any url param
38 |  *  total_fee WeChat use Fen not Yuan as unit
39 |  */
40 | 
41 | $config = require_once('./config.php');
42 | 
43 | $config = $config['wechat'];
44 | 
45 | /**
46 |  * 跳转到支付界面
47 |  * @param $config
48 |  */
49 | function wechat_redirect($config)
50 | {
51 |     /*
52 |      * @var Omnipay\Wechat\ExpressGateway
53 |      */
54 |     try
55 |     {
56 | //        $gateway = \Omnipay\Omnipay::create('Wechat_Express');
57 |         $gateway = new \Omnipay\Wechat\ExpressGateway();
58 | 
59 |         $gateway->setAppId($config['app_id']);
60 |         $gateway->setKey($config['pay_sign_key']);
61 |         $gateway->setPartner($config['partner']);
62 |         $gateway->setPartnerKey($config['partner_key']);
63 | 
64 |         $gateway->setNotifyUrl($config['notify_url']);
65 |         $gateway->setReturnUrl($config['return_url']);
66 |         $gateway->setReturnUrl($config['cancel_url']);
67 | 
68 |         $out_trade_no = $_GET['out_trade_no'];
69 |         $opts = array(
70 |             'subject' => $_GET['subject'],
71 |             'description' => '微信无效',
72 |             'total_fee' => $_GET['total_fee'],
73 |             'out_trade_no' => $out_trade_no,
74 |         );
75 |         $res = $gateway->purchase($opts)->send();
76 |         $cache = get_cache();
77 |         $cache->save($out_trade_no, $opts);
78 | 
79 |         if (!empty($_GET['redirect']))
80 |         {
81 |             $res->redirect('js');
82 |         }
83 |         $res->redirect();
84 |     } catch (\Exception $e)
85 |     {
86 |         var_dump($e->getMessage());
87 |     }
88 | }
89 | 
90 | wechat_redirect($config);
91 | 
92 | 93 | 94 | 95 | --------------------------------------------------------------------------------