| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- <?php
- namespace common\components\payment;
- use common\enums\StatusEnum;
- use Yii;
- use Omnipay\Omnipay;
- use Omnipay\Alipay\Responses\AopTradeAppPayResponse;
- use Omnipay\Alipay\Responses\AopTradePreCreateResponse;
- use Omnipay\Alipay\Responses\AopTradeWapPayResponse;
- /**
- * Class AliPay
- * @package common\components\payment
- */
- class AliPay
- {
- protected $config;
- const PC = 'Alipay_AopPage';
- const APP = 'Alipay_AopApp';
- const F2F = 'Alipay_AopF2F';
- const WAP = 'Alipay_AopWap';
- const JS = 'Alipay_AopJs';
- protected $alipay_root_cert_sn = '687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6';
- /**
- * @var \Closure
- */
- protected $getData;
- public function __construct($config)
- {
- $this->config = $config;
- // 重构AopRequest所需要的数据
- $this->getData = function () {
- $this->validateParams();
- // $this->getCertSN();
- if (strtoupper($this->getSignType()) === 'RSA2') {
- $alipayRootCert = $this->getAlipayRootCert();
- $appCert = $this->getAppCert();
- if (is_file($alipayRootCert) && is_file($appCert)) {
- // $this->setParameter('alipay_root_cert_sn', getRootCertSN($alipayRootCert));
- $this->setParameter('alipay_root_cert_sn', '687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6');
- $this->setParameter('app_cert_sn', getCertSN($appCert));
- }
- }
- $this->setDefaults();
- $this->convertToString();
- $data = $this->getParameters();
- $data['method'] = $this->method;
- ksort($data);
- $data['sign'] = $this->sign($data, $this->getSignType());
- return $data;
- };
- }
- /**
- * 实例化类
- *
- * @param string $type
- * @return \Omnipay\Alipay\AopPageGateway
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- private function create($type = self::PC)
- {
- /* @var $gateway \Omnipay\Alipay\AopPageGateway */
- $gateway = Omnipay::create($type);
- $gateway->setSignType('RSA2'); // RSA/RSA2/MD5
- $gateway->setAppId($this->config['app_id']);
- $gateway->setPrivateKey($this->config['private_key']);
- if (!empty($this->config['is_use_cert'])) {
- $gateway->setAlipayPublicCert($this->config['alipay_public_cert']);
- $gateway->setAppCert($this->config['app_cert']);
- $gateway->setAlipayRootCert($this->config['alipay_root_cert']);
- } else {
- $gateway->setAlipayPublicKey($this->config['ali_public_key']);
- }
- $gateway->setNotifyUrl($this->config['notify_url']);
- !empty($this->config['return_url']) && $gateway->setReturnUrl($this->config['return_url']);
- $this->config['sandbox'] === true && $gateway->sandbox();
- return $gateway;
- }
- /**
- * 电脑网站支付
- *
- * @param $config
- *
- * 参数说明
- * $config = [
- * 'subject' => 'test',
- * 'out_trade_no' => date('YmdHis') . mt_rand(1000, 9999),
- * 'total_amount' => '0.01',
- * ]
- *
- * @return string
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function pc($order, $debug = false)
- {
- $order['product_code'] = 'FAST_INSTANT_TRADE_PAY';
- $gateway = $this->create(self::PC);
- $gateway->setParameter('return_url', $this->config['return_url']);
- /** @var \Omnipay\Alipay\Requests\AopTradePagePayRequest $request */
- $request = $gateway->purchase();
- $request->setBizContent($order);
- /** @var \Omnipay\Common\Message\AbstractResponse $response */
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- $redirectUrl = $response->getRedirectUrl();
- /**
- * 直接跳转
- * return $response->redirect();
- */
- return $debug == true ? $response->getData() : $redirectUrl;
- }
- /**
- * APP支付
- *
- * 参数说明
- * $config = [
- * 'subject' => 'test',
- * 'out_trade_no' => date('YmdHis') . mt_rand(1000, 9999),
- * 'total_amount' => '0.01',
- * ]
- *
- * iOS 客户端
- * [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
- * NSLog(@"reslut = %@",resultDic);
- * }];
- *
- * Android 客户端
- * PayTask alipay = new PayTask(PayDemoActivity.this);
- * Map<String, String> result = alipay.payV2(orderString, true);
- * @param $config
- * @param $notifyUrl
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function app($order, $debug = false)
- {
- $order['product_code'] = 'QUICK_MSECURITY_PAY';
- $gateway = $this->create(self::APP);
- /** @var \Omnipay\Alipay\Requests\AopTradePagePayRequest $request */
- $request = $gateway->purchase();
- $request->setBizContent($order);
- /** @var AopTradeAppPayResponse $response */
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- return $debug == true ? $response->getData() : $response->getOrderString();
- }
- /**
- * 面对面支付
- *
- * @param $order
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function f2f($order, $debug = false)
- {
- $gateway = $this->create(self::F2F);
- /** @var \Omnipay\Alipay\Requests\AopTradePagePayRequest $request */
- $request = $gateway->purchase();
- $request->setBizContent($order);
- /** @var AopTradePreCreateResponse $response */
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- return $debug == true ? $response->getData() : $response->getQrCode();
- }
- /**
- * 手机网站支付
- *
- * @param $order
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function wap($order, $debug = false)
- {
- $order['product_code'] = 'QUICK_WAP_PAY';
- $gateway = $this->create(self::WAP);
- /** @var \Omnipay\Alipay\Requests\AopTradePagePayRequest $request */
- $request = $gateway->purchase();
- $request->setBizContent($order);
- /** @var AopTradeWapPayResponse $response */
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- /**
- * 直接跳转
- * return $response->redirect();
- */
- return $debug == true ? $response->getData() : $response->getRedirectUrl();
- }
- /**
- * 统一收单交易创建接口
- *
- * @param $order
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- * @throws \Exception
- */
- public function js($order, $debug = false)
- {
- $this->config['return_url'] = '';
- $gateway = $this->create(self::JS);
- /** @var \Omnipay\Alipay\Requests\AopTradeCreateRequest $request */
- $request = $gateway->purchase();
- $request->setBizContent($order);
- /** @var AopTradeWapPayResponse $response */
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- if (!empty($response->getData()['alipay_trade_create_response'])) {
- $data = $response->getData()['alipay_trade_create_response'];
- if (empty($data['code']) || $data['code'] != 10000) {
- // 出错
- throw new \Exception($data['sub_msg'] ?? '请求支付宝失败');
- }
- return $data['trade_no'] ?? $data;
- }
- return $response->getData()['alipay_trade_create_response']??$response->getData();
- }
- /**
- * 转账
- *
- * $info = [
- * 'out_biz_no' => '转账单号',
- * 'payee_type' => '收款人账号类型', // ALIPAY_USERID:支付宝唯一号;ALIPAY_LOGONID:支付宝登录号
- * 'payee_account' => '收款人账号',
- * 'amount' => '收款金额',
- * 'payee_real_name' => '收款方真实姓名', // 非必填
- * 'remark' => '账业务的标题,用于在支付宝用户的账单里显示', // 非必填
- * ]
- *
- * payee_type
- * 1、ALIPAY_USERID:支付宝账号对应的支付宝唯一用户号。以2088开头的16位纯数字组成。
- * 2、ALIPAY_LOGONID:支付宝登录号,支持邮箱和手机号格式。
- *
- * 老的接口:
- * https://opendocs.alipay.com/apis/api_28/alipay.fund.trans.toaccount.transfer
- *
- * 新的接口
- * https://opendocs.alipay.com/apis/api_28/alipay.fund.trans.uni.transfer/
- *
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function transfer(array $info)
- {
- !isset($info['payee_type']) && $info['payee_type'] = 'ALIPAY_LOGONID';
- $gateway = $this->create();
- $request = $gateway->transfer();
- $request->setBizContent($info);
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- $data = $response->getData();
- return $data['alipay_fund_trans_toaccount_transfer_response'] ?? '';
- }
- /**
- * 付款到账查询
- *
- * $info = [
- * 'out_biz_no' => '转账单号',
- * 'order_id' => '回调单号',
- * ]
- *
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function transferQuery(array $info)
- {
- $gateway = $this->create();
- $request = $gateway->transferQuery();
- $request->setBizContent($info);
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- $data = $response->getData();
- return $data['alipay_fund_trans_toaccount_transfer_response'] ?? '';
- }
- /**
- * 退款
- *
- * $info = [
- * 'out_trade_no' => 'The existing Order ID',
- * 'trade_no' => 'The Transaction ID received in the previous request',
- * 'refund_amount' => 18.4,
- * 'out_request_no' => date('YmdHis') . mt_rand(1000, 9999)
- * ]
- *
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function refund(array $info)
- {
- $gateway = $this->create();
- $request = $gateway->refund();
- $request->setBizContent($info);
- if (!empty($this->config['is_use_cert'])) {
- $response = $request->sendData($this->getData->call($request));
- } else {
- $response = $request->send();
- }
- return $this->check_refund_response($response->getData());
- //return $response->getData();
- }
- /**
- * 扫码收款
- *
- * @return mixed
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function capture()
- {
- $gateway = $this->create('Alipay_AopF2F');
- $request = $gateway->capture();
- return $request;
- }
- /**
- * 异步/同步通知
- *
- * @return \Omnipay\Alipay\Requests\AopCompletePurchaseRequest
- * @throws \Omnipay\Common\Exception\InvalidRequestException
- */
- public function notify()
- {
- $gateway = $this->create();
- $request = $gateway->completePurchase();
- $request->setParams(array_merge(Yii::$app->request->post(), Yii::$app->request->get())); // Optional
- return $request;
- }
- /**
- * 检测退款返回结果
- * @param $response
- * @return array
- * @throws \Exception
- */
- public function check_refund_response($response)
- {
- Yii::error('alipay_trade_refund_response :'.json_encode($response));
- $alipay_trade_refund_response = $response['alipay_trade_refund_response'] ?? [];
- if($alipay_trade_refund_response['code'] !== '10000'){
- throw new \Exception($alipay_trade_refund_response['sub_msg']);
- }
- $return = [];
- if($alipay_trade_refund_response['fund_change'] == 'Y'){
- //有资金变化:退款成功
- $return['is_success'] = true;
- $return['fund_change'] = true;
- }else{
- //无资金变化
- $return['is_success'] = true;
- $return['fund_change'] = false;
- $return['msg'] = '本次请求没有资金变动,请到支付宝平台查看交易';
- }
- return $return;
- }
- }
|