sand_box = $boolean; } /** * 创建支付宝AOP * * @return AopPageGateway */ public function createAop(array $setting = []) { if (empty($setting) && empty($this->mall_id)) throw new \Exception('未定义Mall-Id'); if (empty($setting)) $setting = (new SettingService($this->mall_id))->getSetting(); /** * @var \Omnipay\Alipay\AopPageGateway */ $this->aop = Omnipay::create('Alipay_AopWap'); $this->aop->setSignType('RSA2'); // RSA/RSA2/MD5. Use certificate mode must set RSA2 $this->aop->setAppId($setting['app_id']); $this->aop->setPrivateKey(trim($setting['private_key'])); $this->aop->setAlipayPublicKey(trim($setting['alipay_public_key'])); // 回调地址 $this->aop->setNotifyUrl( $this->getNotifyUrl() ); // 设置沙盒 $this->sand_box && $this->aop->sandbox(); return $this->aop; } /** * 单笔转账 * * @param float $money * @param string $name * @param string $account * @param string $order_sn * @param string $payee_type * @param string $remark * @return array|string */ public function transfer( float $money, string $name, string $account, string $order_sn, string $remark = AlitoapyEnum::DEF_REMARK, string $payee_type = 'ALIPAY_LOGON_ID' ) { $data = [ 'out_biz_no' => $order_sn, 'trans_amount' => $money, 'order_title' => $remark, 'remark' => $remark, 'payee_info' => [ 'identity_type' => $payee_type, 'identity' => $account, 'name' => $name, ] ]; try { return $this->alipayFundTransUniTransfer($data); } catch (Exception $e) { Yii::$app->custom->logs(FormatHelper::exception($e, '支付宝代付提现失败'), compact('data')); return ['code' => -1, 'sub_msg' => '系统异常', 'msg' => '系统异常']; } } private function isCreatedAop() { if ($this->aop === null) $this->createAop(); } /** * 获取回调地址 * * @return string */ private function getNotifyUrl() { return Yii::$app->services->setting->platform->get('system.api_url') . static::URI; } public function getAopClient(){ if (empty($setting) && empty($this->mall_id)) throw new \Exception('未定义Mall-Id'); if (empty($setting)) $setting = (new SettingService($this->mall_id))->getSetting(); $aop = new AopClient(); $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do'; $aop->appId = $setting['app_id']; $aop->rsaPrivateKey = trim($setting['private_key']); $aop->alipayrsaPublicKey=trim($setting['alipay_public_key']); $aop->apiVersion = '1.0'; $aop->signType = 'RSA2'; $aop->postCharset='UTF-8'; $aop->format='json'; return $aop; } /** * 获取配置 * * 这个方法是复制上面的getAopClient * 因为上面的方法是有缺失的,但是不删,因为或许其他地方有用到 * 所以针对“申请电子回单”的功能,用这个新方法,且这个“申请电子回单”的功能按照原来的代码,本就一直就用不了的 * 此新方法与原方法的区别是:获取的配置rsaPrivateKey、alipayrsaPublicKey,是用全局的支付宝配置,并不是用“支付宝代付”的配置 * * @throws \Exception 当未定义Mall-Id时抛出异常 * @return AopClient 初始化的支付宝客户端对象 */ public function getAopClientMall() { if (empty($setting) && empty($this->mall_id)) throw new \Exception('未定义Mall-Id'); if (empty($setting)) $setting = (new SettingService($this->mall_id))->getSetting(); $settingMall = \Yii::$app->services->setting->mall->get($this->mall_id, 'pay'); $settingMall = json_decode($settingMall['alipay'], true); $aop = new AopClient(); $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do'; $aop->appId = $settingMall['alipay_app_id']; $aop->rsaPrivateKey = trim($settingMall['alipay_private_key']); $aop->alipayrsaPublicKey = trim($settingMall['alipay_public_key']); $aop->apiVersion = '1.0'; $aop->signType = 'RSA2'; $aop->postCharset = 'UTF-8'; $aop->format = 'json'; return $aop; } /** * 获取 "alipay.fund.trans.uni.transfer(单笔转账接口)" 配置 * * @param array $setting * * @return AlipayConfig * @throws Exception */ protected function getAlipayConfig(array $setting = []) { if (empty($setting) && empty($this->mall_id)) throw new Exception('未定义Mall-Id'); if (empty($setting)) $setting = (new SettingService($this->mall_id))->getSetting(); $alipayConfig = new AlipayConfig(); $alipayConfig->setPrivateKey($setting['private_key']); $alipayConfig->setServerUrl('https://openapi.alipay.com/gateway.do'); $alipayConfig->setAppId($setting['app_id']); $alipayConfig->setCharset('UTF-8'); $alipayConfig->setSignType('RSA2'); $alipayConfig->setFormat('json'); $alipayConfig->setAppCertContent($setting['app_cert']); $alipayConfig->setAlipayPublicCertContent($setting['alipay_public_key']); $alipayConfig->setRootCertContent($setting['root_cert']); return $alipayConfig; } /** * 调用 alipay.fund.trans.uni.transfer(单笔转账接口) * * @param array $data * * @return array * @throws Exception */ protected function alipayFundTransUniTransfer(array $data = []): array { // 初始化SDK $alipayClient = new AopCertClient($this->getAlipayConfig()); // 构造请求参数以调用接口 $request = new AlipayFundTransUniTransferRequest(); // 设置描述特定的业务场景 !isset($data['biz_scene']) && $data['biz_scene'] = "DIRECT_TRANSFER"; // 设置业务产品码 !isset($data['product_code']) && $data['product_code'] = "TRANS_ACCOUNT_NO_PWD"; $request->setBizContent(json_encode($data,JSON_UNESCAPED_UNICODE)); $responseResult = $alipayClient->execute($request); $responseApiName = str_replace(".","_",$request->getApiMethodName())."_response"; $response = $responseResult->$responseApiName; Yii::$app->custom->logs('支付宝代付请求', [ 'res' => $response, 'data' => $data ]); if (empty($response)) { throw new RuntimeException('alipay.fund.trans.uni.transfer(单笔转账接口) 响应空'); } if (is_array($response)) { return $response; } if (!is_object($response)) { throw new RuntimeException('alipay.fund.trans.uni.transfer(单笔转账接口) 响应参数类型错误'); } return ArrayHelper::toArray($response); } }