PaymentController.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Http\Models\Goods;
  4. use App\Http\Models\Paypal;
  5. use Illuminate\Http\Request;
  6. use Response;
  7. use Redirect;
  8. use Cache;
  9. use Log;
  10. use PayPal\Api\Amount;
  11. use PayPal\Api\Details;
  12. use PayPal\Api\Item;
  13. use PayPal\Api\ItemList;
  14. use PayPal\Api\Payer;
  15. use PayPal\Api\Payment;
  16. use PayPal\Api\PaymentExecution;
  17. use PayPal\Api\RedirectUrls;
  18. use PayPal\Api\Transaction;
  19. use PayPal\Api\ShippingAddress;
  20. use PayPal\Rest\ApiContext;
  21. use PayPal\Auth\OAuthTokenCredential;
  22. class PaymentController extends Controller
  23. {
  24. protected static $config;
  25. private $apiContext;
  26. function __construct()
  27. {
  28. self::$config = $this->systemConfig();
  29. $this->apiContext = new ApiContext(
  30. new OAuthTokenCredential(self::$config['paypal_client_id'], self::$config['paypal_client_secret'])
  31. );
  32. $this->apiContext->setConfig([
  33. 'mode' => 'sandbox',
  34. 'log.LogEnabled' => true,
  35. 'log.FileName' => storage_path('logs/paypal.log'),
  36. 'log.LogLevel' => 'DEBUG', // 测试DEBUG,生产环境INFO
  37. 'cache.enabled' => true,
  38. // 'http.CURLOPT_CONNECTTIMEOUT' => 30
  39. // 'http.headers.PayPal-Partner-Attribution-Id' => '123123123'
  40. //'log.AdapterFactory' => '\PayPal\Log\DefaultLogFactory' // Factory class implementing \PayPal\Log\PayPalLogFactory
  41. ]);
  42. }
  43. // 创建支付
  44. public function create(Request $request)
  45. {
  46. $oid = $request->get('oid');
  47. $goods_id = $request->get('goods_id');
  48. $user = $request->session()->get('user');
  49. // 商品信息
  50. $goods = Goods::query()->where('id', $goods_id)->first();
  51. if (!$goods) {
  52. //TODO:购买商品页需要做判断,出现异常时挂掉
  53. $request->session()->flash('paypalErrorMsg', '创建支付订单失败:所购服务不存在');
  54. return Redirect::back();
  55. }
  56. // 设置支付信息
  57. $payer = new Payer();
  58. $payer->setPaymentMethod("paypal");
  59. // 设置所购商品信息,包含名称、数量、SKU、价格
  60. $item1 = new Item();
  61. $item1->setName($goods->name)->setCurrency('USD')->setQuantity(1)->setSku($goods->sku)->setPrice($goods->price / 100);
  62. $itemList = new ItemList();
  63. $itemList->setItems([$item1]);
  64. /*
  65. // 设定收货地址信息,防止用户自付款时可改
  66. $address = new ShippingAddress();
  67. $address->setRecipientName($user['username'])
  68. ->setLine1('余杭区')
  69. ->setLine2('文一西路969号西溪园区')
  70. ->setCity('杭州市')
  71. ->setState('浙江省')
  72. ->setPhone('+8613800000000')
  73. ->setPostalCode('311100')
  74. ->setCountryCode('CN');
  75. // 商品列表写入设定好的地址信息
  76. $itemList->setShippingAddress($address);
  77. */
  78. // 设置单据运费、税费、小计算
  79. $details = new Details();
  80. $details->setShipping(0)->setTax(0)->setSubtotal($goods->price / 100);
  81. // 设定单据金额
  82. $amount = new Amount();
  83. $amount->setCurrency("USD")->setTotal($goods->price / 100)->setDetails($details);
  84. // 跳转页
  85. $redirectUrls = new RedirectUrls();
  86. $redirectUrls->setReturnUrl(url("payment/execute?subtotal=" . $goods->price / 100))->setCancelUrl(url("payment/cancel"));
  87. // 设定交易描述
  88. $transaction = new Transaction();
  89. $transaction->setAmount($amount)->setItemList($itemList)->setDescription("购买虚拟服务")->setInvoiceNumber(uniqid());
  90. // 创建支付
  91. $payment = new Payment();
  92. $payment->setIntent("sale")->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]);
  93. try {
  94. $payment->create($this->apiContext);
  95. } catch (\Exception $ex) {
  96. Log::error($ex->getMessage());
  97. Log::error('PayPal授权失败,可能是接口配置错误');
  98. $request->session()->flash('paypalErrorMsg', 'PayPal授权失败,可能是接口配置错误');
  99. return Redirect::back();
  100. }
  101. // 得到支付授权跳转页(给用户点确认付款用)
  102. $approvalUrl = $payment->getApprovalLink();
  103. return Redirect::to($approvalUrl);
  104. }
  105. // 执行支付
  106. public function execute(Request $request)
  107. {
  108. \Log::info('execute_params:' . var_export($request->all(), true));
  109. $subtotal = $request->get('subtotal');
  110. $paymentId = $request->get('paymentId');
  111. $token = $request->get('token');
  112. $PayerID = $request->get('PayerID');
  113. if (empty($paymentId) || empty($token) || empty($PayerID)) {
  114. $request->session()->flash('paypalErrorMsg', '支付回调地址错误');
  115. return Redirect::to('user/goodsList');
  116. } else {
  117. // 根据支付单据获取支付信息
  118. $payment = Payment::get($paymentId, $this->apiContext);
  119. $details = new Details();
  120. $details->setShipping(0)->setTax(0)->setSubtotal($subtotal);
  121. $amount = new Amount();
  122. $amount->setCurrency('USD')->setTotal($subtotal)->setDetails($details);
  123. $transaction = new Transaction();
  124. $transaction->setAmount($amount);
  125. // 执行支付
  126. $execution = new PaymentExecution();
  127. $execution->setPayerId($PayerID)->addTransaction($transaction);
  128. try {
  129. $result = $payment->execute($execution, $this->apiContext);
  130. \Log::info(var_export($result, true));
  131. // 支付成功,写入支付单据信息
  132. } catch (\Exception $ex) {
  133. var_dump($ex);
  134. echo "支付失败";
  135. exit(1);
  136. }
  137. \Log::info(var_export($payment, true));
  138. return $payment;
  139. }
  140. }
  141. // 取消支付
  142. public function cancel(Request $request)
  143. {
  144. var_dump($request->all());
  145. echo '取消支付';
  146. }
  147. // 查询支付状态
  148. public function query()
  149. {
  150. }
  151. // 写入日志
  152. private function log($oid, $invoice_number = '', $items = '', $response_data = '', $error = '')
  153. {
  154. $paypal = new Paypal();
  155. $paypal->oid = $oid;
  156. $paypal->invoice_number = $invoice_number;
  157. $paypal->items = $items;
  158. $paypal->response_data = $response_data;
  159. $paypal->error = $error;
  160. $paypal->save();
  161. return $paypal->id;
  162. }
  163. }