123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- <?php
- namespace app\api\controller\xmwechat;
- use app\common\controller\Frontend;
- use app\common\library\xmwechat\payment\PartnerPayService;
- use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
- use EasyWeChat\Kernel\Exceptions\RuntimeException;
- use EasyWeChat\Pay\Application;
- use EasyWeChat\Pay\Message;
- use think\facade\Db;
- use think\facade\Log;
- use think\Request;
- /**
- * 合作伙伴(服务商模式支付)
- */
- class PartnerPayment extends Frontend
- {
- // 数组中的 pay、refunds 请在调试完成后删除,支付、退款接口需要登录
- protected array $noNeedLogin = ['pay', 'refunds', 'payNotify', 'refundsNotify'];
- protected array $partnerPaymentConfig;
- protected array $wechatPartnerConfig;
- public function initialize(): void
- {
- parent::initialize();
- $config = config('xmwechat');
- $this->partnerPaymentConfig = $config['partnerPayment'];
- $this->wechatPartnerConfig = [
- 'mch_id' => $this->partnerPaymentConfig['sp_mchid'],
- 'secret_key' => $this->partnerPaymentConfig['secret_key'],
- 'certificate' => $this->partnerPaymentConfig['certificate'],
- 'private_key' => $this->partnerPaymentConfig['sp_mchid'],
- 'notify_url' => $this->partnerPaymentConfig['notify_url'],
- 'http' => [
- 'throw' => true, // 状态码非 200、300 时是否抛出异常,默认为开启
- 'timeout' => 5.0,
- ],
- ];
- }
- /**
- * 微信公众号、小程序支付示例(合作伙伴服务商模式)
- * 支付接口是需要登录的,测试结束后,请在最上方$noNeedLogin数组中去掉 pay
- * @param Request $request
- * @return void
- * @throws \Exception
- * @author jsjxsz
- * order_no 订单号
- * body 描述
- * pay_price 支付金额
- * openid 用户openid
- * transaction_no 交易号
- */
- public function pay(Request $request): void
- {
- if ($request->isPost()) {
- $params = $request->only(['order_no', 'body', 'pay_price', 'openid', 'transaction_no']);
- // miniProgram: 小程序支付; offiAccount: 公众号支付
- $params['pay_type'] = 'miniProgram';
- $result = PartnerPayService::getInstance()->pay($params);
- if ($result !== false) {
- $this->success('success', $result);
- } else {
- $this->error('error');
- }
- }
- }
- /**
- * 退款申请(退款状态需在退款回调中获取)
- * @param Request $request
- * @return void
- * @author jsjxsz
- * out_trade_no 原支付交易对应的商户订单号
- * out_refund_no 商户退款单号,商户系统内部的退款单号,退款时生成,唯一
- * reason 退款原因
- * refund_price 退款金额
- * pay_price 原交易金额
- */
- public function refunds(Request $request): void
- {
- if ($request->isPost()) {
- $params = $request->only(['pay_price', 'refund_price', 'out_trade_no','out_refund_no','reason']);
- $result = PartnerPayService::getInstance()->refunds($params);
- if ($result !== false) {
- $this->success('success', $result);
- } else {
- $this->error('error');
- }
- }
- }
- /**
- * 服务商模式支付回调
- * 注意仔细看下面的注释内容
- * @return \Psr\Http\Message\ResponseInterface|void
- * @author jsjxsz
- */
- public function payNotify()
- {
- try {
- $app = new Application($this->wechatPartnerConfig);
- $server = $app->getServer();
- $server->handlePaid(function (Message $message, \Closure $next) use ($app) {
- $noyifyData = json_decode($message, true);
- $success_time = strtotime($noyifyData['success_time']);
- $out_trade_no = $noyifyData['out_trade_no'];
- /**
- * 这里写你自己的逻辑 start
- */
- // 这里查询你自己的数据表!!!
- $order = Db::name('order')->where('transaction_no', $out_trade_no)->find();
- if (!$order || $order['pay_status'] == 1) {
- // 如果订单不存在 或者 订单已经支付过了
- // 告诉微信,我已经处理完了,订单没找到,别再通知我了
- return ['code' => 'SUCCESS', 'message' => '成功'];
- }
- // return_code 表示通信状态,不代表支付状态
- if ($noyifyData['trade_state'] === 'SUCCESS') {
- // pay success
- $total_fee = $noyifyData['amount']['payer_total'] / 100;//单位分
- // 这里写你自己的回调逻辑
- } elseif ($message['result_code'] === 'FAIL') {
- // pay fail
- }
- /**
- * 这里写你自己的逻辑 end
- */
- return $next($message);
- });
- return $server->serve();
- } catch (InvalidArgumentException|RuntimeException|\ReflectionException|\Throwable $e) {
- Log::info('服务商微信支付回调通知:' . $e->getMessage());
- }
- }
- /**
- * 服务商模式退款回调
- * 注意仔细看下面的注释内容
- * @return \Psr\Http\Message\ResponseInterface|void
- * @author jsjxsz
- */
- public function refundsNotify()
- {
- try {
- $app = new Application($this->wechatPartnerConfig);
- $server = $app->getServer();
- $server->handleRefunded(function (Message $message, \Closure $next) use ($app) {
- $noyifyData = json_decode($message, true);
- $success_time = strtotime($noyifyData['success_time']); // 退款时间
- $out_refund_no = $noyifyData['out_refund_no'];
- /**
- * 这里写你自己的逻辑 start
- */
- // 这里查询你自己的数据表!!!
- $order_refunds = Db::name('order_refunds')->where('out_refund_no', $out_refund_no)->find();
- if (!$order_refunds || $order_refunds['refund_status'] == 1) {
- // 如果订单不存在 或者 订单已经支付过了
- // 告诉微信,我已经处理完了,订单没找到,别再通知我了
- return ['code' => 'SUCCESS', 'message' => '成功'];
- }
- // return_code 表示通信状态,不代表支付状态
- if ($noyifyData['refund_status'] === 'SUCCESS') {
- // success
- } elseif ($message['result_code'] === 'FAIL') {
- // pay fail
- }
- /**
- * 这里写你自己的逻辑 end
- */
- return $next($message);
- });
- return $server->serve();
- } catch (InvalidArgumentException|RuntimeException|\ReflectionException|\Throwable $e) {
- Log::info('服务商微信退款回调通知:' . $e->getMessage());
- }
- }
- }
|