飞道的博客

laravel对接支付宝和微信支付第三方支付

341人阅读  评论(0)

使用插件:

https://packagist.org/packages/yansongda/pay

1、注册服务,,调用 Yansongda\Pay 来创建一个支付宝支付对象

2、配置文件

3、代码控制器


  
  1. <?php
  2. namespace App\ Http\ Controllers;
  3. use App\ Events\ OrderPaid;
  4. use App\ Exceptions\ InvalidRequestException;
  5. use App\ Models\ Order;
  6. use Carbon\ Carbon;
  7. use Endroid\ QrCode\ QrCode;
  8. use Illuminate\ Http\ Request;
  9. class PaymentController extends Controller
  10. {
  11. public function payByAlipay(Order $order, Request $request)
  12. {
  13. // 判断订单是否属于当前用户
  14. $this->authorize( 'own', $order);
  15. // 订单已支付或者已关闭
  16. if ($order->paid_at || $order->closed) {
  17. throw new InvalidRequestException( '订单状态不正确');
  18. }
  19. // 调用支付宝的网页支付
  20. return app( 'alipay')->web([
  21. 'out_trade_no' => $order->no, // 订单编号,需保证在商户端不重复
  22. 'total_amount' => $order->total_amount, // 订单金额,单位元,支持小数点后两位
  23. 'subject' => '支付 Laravel Shop 的订单:'.$order->no, // 订单标题
  24. ]);
  25. }
  26. public function alipayReturn()
  27. {
  28. try {
  29. app( 'alipay')->verify();
  30. } catch (\ Exception $e) {
  31. return view( 'pages.error', [ 'msg' => '数据不正确']);
  32. }
  33. return view( 'pages.success', [ 'msg' => '付款成功']);
  34. }
  35. public function alipayNotify()
  36. {
  37. // 校验输入参数
  38. $data = app( 'alipay')->verify();
  39. // 如果订单状态不是成功或者结束,则不走后续的逻辑
  40. // 所有交易状态:https://docs.open.alipay.com/59/103672
  41. if(!in_array($data->trade_status, [ 'TRADE_SUCCESS', 'TRADE_FINISHED'])) {
  42. return app( 'alipay')->success();
  43. }
  44. // $data->out_trade_no 拿到订单流水号,并在数据库中查询
  45. $order = Order::where( 'no', $data->out_trade_no)->first();
  46. // 正常来说不太可能出现支付了一笔不存在的订单,这个判断只是加强系统健壮性。
  47. if (!$order) {
  48. return 'fail';
  49. }
  50. // 如果这笔订单的状态已经是已支付
  51. if ($order->paid_at) {
  52. // 返回数据给支付宝
  53. return app( 'alipay')->success();
  54. }
  55. $order->update([
  56. 'paid_at' => Carbon::now(), // 支付时间
  57. 'payment_method' => 'alipay', // 支付方式
  58. 'payment_no' => $data->trade_no, // 支付宝订单号
  59. ]);
  60. $this->afterPaid($order);
  61. return app( 'alipay')->success();
  62. }
  63. public function payByWechat(Order $order, Request $request)
  64. {
  65. $this->authorize( 'own', $order);
  66. if ($order->paid_at || $order->closed) {
  67. throw new InvalidRequestException( '订单状态不正确');
  68. }
  69. // 之前是直接返回,现在把返回值放到一个变量里
  70. $wechatOrder = app( 'wechat_pay')->scan([
  71. 'out_trade_no' => $order->no,
  72. 'total_fee' => $order->total_amount * 100,
  73. 'body' => '支付 Laravel Shop 的订单:'.$order->no,
  74. ]);
  75. // 把要转换的字符串作为 QrCode 的构造函数参数
  76. $qrCode = new QrCode($wechatOrder->code_url);
  77. // 将生成的二维码图片数据以字符串形式输出,并带上相应的响应类型
  78. return response($qrCode->writeString(), 200, [ 'Content-Type' => $qrCode->getContentType()]);
  79. }
  80. public function wechatNotify()
  81. {
  82. // 校验回调参数是否正确
  83. $data = app( 'wechat_pay')->verify();
  84. // 找到对应的订单
  85. $order = Order::where( 'no', $data->out_trade_no)->first();
  86. // 订单不存在则告知微信支付
  87. if (!$order) {
  88. return 'fail';
  89. }
  90. // 订单已支付
  91. if ($order->paid_at) {
  92. // 告知微信支付此订单已处理
  93. return app( 'wechat_pay')->success();
  94. }
  95. // 将订单标记为已支付
  96. $order->update([
  97. 'paid_at' => Carbon::now(),
  98. 'payment_method' => 'wechat',
  99. 'payment_no' => $data->transaction_id,
  100. ]);
  101. $this->afterPaid($order);
  102. return app( 'wechat_pay')->success();
  103. }
  104. protected function afterPaid(Order $order)
  105. {
  106. event( new OrderPaid($order));
  107. }
  108. public function wechatRefundNotify(Request $request)
  109. {
  110. // 给微信的失败响应
  111. $failXml = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[FAIL]]></return_msg></xml>';
  112. $data = app( 'wechat_pay')->verify( null, true);
  113. // 没有找到对应的订单,原则上不可能发生,保证代码健壮性
  114. if(!$order = Order::where( 'no', $data[ 'out_trade_no'])->first()) {
  115. return $failXml;
  116. }
  117. if ($data[ 'refund_status'] === 'SUCCESS') {
  118. // 退款成功,将订单退款状态改成退款成功
  119. $order->update([
  120. 'refund_status' => Order::REFUND_STATUS_SUCCESS,
  121. ]);
  122. } else {
  123. // 退款失败,将具体状态存入 extra 字段,并表退款状态改成失败
  124. $extra = $order->extra;
  125. $extra[ 'refund_failed_code'] = $data[ 'refund_status'];
  126. $order->update([
  127. 'refund_status' => Order::REFUND_STATUS_FAILED,
  128. 'extra' => $extra
  129. ]);
  130. }
  131. return app( 'wechat_pay')->success();
  132. }
  133. }

4、说明

该文档为 v2.x 版本,如果您想找 v1.x 版本文档,请点击https://github.com/yansongda/pay/tree/v1.x

注意:v1.x 与 v2.x 版本不兼容

开发了多次支付宝与微信支付后,很自然产生一种反感,惰性又来了,想在网上找相关的轮子,可是一直没有找到一款自己觉得逞心如意的,要么使用起来太难理解,要么文件结构太杂乱,只有自己撸起袖子干了。

!!请先熟悉 支付宝/微信 说明文档!!请具有基本的 debug 能力!!

6、官方文档地址:


  
  1. https:/ /opendocs.alipay.com/apis /api_1
  2. https:/ /pay.weixin.qq.com/wiki /doc/api /index.html

2021年5月17日17:59:42

 

 


转载:https://blog.csdn.net/php_xml/article/details/116942197
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场