Payment.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. namespace app\api\controller\xmwechat;
  3. use app\common\controller\Frontend;
  4. use app\common\library\xmwechat\payment\PayService;
  5. use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
  6. use EasyWeChat\Kernel\Exceptions\RuntimeException;
  7. use EasyWeChat\Pay\Application;
  8. use EasyWeChat\Pay\Message;
  9. use think\facade\Db;
  10. use think\facade\Log;
  11. use think\Request;
  12. class Payment extends Frontend
  13. {
  14. // 数组中的 pay 请在调试完成后删除,支付接口需要登录
  15. protected array $noNeedLogin = ['pay', 'notify'];
  16. protected array $wechatPayConfig;
  17. public function initialize(): void
  18. {
  19. parent::initialize();
  20. $config = config('xmwechat');
  21. $this->wechatPayConfig = $config['payment'];
  22. }
  23. /**
  24. * 微信公众号、小程序支付示例
  25. * 支付接口是需要登录的,测试结束后,请在最上方$noNeedLogin数组中去掉 pay
  26. * @param Request $request
  27. * @return void
  28. * @throws \Exception
  29. * @author jsjxsz
  30. */
  31. public function pay(Request $request): void
  32. {
  33. if ($request->isPost()) {
  34. // order_no:订单号 body:描述 pay_price:支付金额 openid:用户openid transaction_no:交易号
  35. $params = $request->only(['order_no', 'body', 'pay_price', 'openid', 'transaction_no']);
  36. // miniProgram: 小程序支付; offiAccount: 公众号支付
  37. $params['pay_type'] = 'miniProgram';
  38. $result = PayService::getInstance()->pay($params);
  39. if ($result !== false) {
  40. $this->success('success', $result);
  41. } else {
  42. $this->error('error');
  43. }
  44. }
  45. }
  46. /**
  47. * 微信公众号、小程序支付回调
  48. * 注意仔细看下面的注释内容
  49. * @author jsjxsz
  50. */
  51. public function notify()
  52. {
  53. try {
  54. $app = new Application([
  55. 'mch_id' => $this->wechatPayConfig['mch_id'],
  56. 'secret_key' => $this->wechatPayConfig['secret_key'],
  57. 'certificate' => root_path() . $this->wechatPayConfig['certificate'],
  58. 'private_key' => root_path() . $this->wechatPayConfig['private_key'],
  59. 'notify_url' => $this->wechatPayConfig['notify_url'],
  60. 'http' => [
  61. 'throw' => true, // 状态码非 200、300 时是否抛出异常,默认为开启
  62. 'timeout' => 5.0,
  63. ],
  64. ]);
  65. $server = $app->getServer();
  66. $server->handlePaid(function (Message $message, \Closure $next) use ($app) {
  67. $noyifyData = json_decode($message, true);
  68. $pay_time = strtotime($noyifyData['success_time']);
  69. $time = time();
  70. $order_no = $noyifyData['out_trade_no'];
  71. $transaction_id = $noyifyData['transaction_id'];
  72. $amount = $noyifyData['amount']['payer_total'] / 100;//单位分
  73. /**
  74. * 这里写你自己的逻辑 start
  75. */
  76. // 这里查询你自己的数据表!!!
  77. $order = Db::name('order')->where('order_no', $order_no)->find();
  78. if (!$order || $order['pay_status'] == 1) {
  79. // 如果订单不存在 或者 订单已经支付过了
  80. // 告诉微信,我已经处理完了,订单没找到,别再通知我了
  81. return ['code' => 'SUCCESS', 'message' => '成功'];
  82. }
  83. // return_code 表示通信状态,不代表支付状态
  84. if ($noyifyData['trade_state'] === 'SUCCESS') {
  85. // 支付成功
  86. // 写你自己的逻辑
  87. } else if ($message['result_code'] === 'FAIL') {
  88. // 支付失败
  89. // 写你自己的逻辑
  90. }
  91. /**
  92. * 这里写你自己的逻辑 end
  93. */
  94. return $next($message);
  95. });
  96. return $server->serve();
  97. } catch (InvalidArgumentException|RuntimeException|\ReflectionException|\Throwable $e) {
  98. $this->error($e->getMessage());
  99. }
  100. }
  101. }