Sfoglia il codice sorgente

paypal支付接入

zhangdehua 1 anno fa
parent
commit
e8e2f051e2

+ 35 - 0
app/api/controller/Checkout.php

@@ -13,10 +13,13 @@ declare (strict_types=1);
 namespace app\api\controller;
 
 use app\api\model\Order as OrderModel;
+use app\api\service\order\PaySuccess;
 use app\api\service\User as UserService;
 use app\api\service\Cart as CartService;
 use app\api\service\order\Checkout as CheckoutService;
 use app\api\validate\order\Checkout as CheckoutValidate;
+use app\common\enum\order\PayType as OrderPayTypeEnum;
+use app\common\library\paypal\PayPal;
 use cores\exception\BaseException;
 use think\response\Json;
 
@@ -140,6 +143,9 @@ class Checkout extends Controller
         $CartModel = new CartService;
         // 购物车商品列表
         $goodsList = $CartModel->getOrderGoodsList($cartIds);
+        if (empty($goodsList)) {
+            return $this->renderError('请选择商品结算');
+        }
         // 获取订单结算信息
         $orderInfo = $Checkout->onCheckout($goodsList);
         if ($this->request->isGet()) {
@@ -170,6 +176,35 @@ class Checkout extends Controller
     }
 
     /**
+     * returnUrl回来时继续调用执行扣款接口paypal
+     * @return Json
+     */
+    public function payPayExecutePay($orderNo)
+    {
+        if (empty($orderNo)){
+            return $this->renderError('something wrong!');
+        }
+        //dd($orderNo);
+        //$paymentId = 'PAYID-MXUYFIQ9KF846046B114514M';
+        $paymentId = $this->request->param('paymentId');
+        //$token = $this->request->param('token');
+        //$PayerID = $this->request->param('PayerID');
+        $conf = config('paypal');
+        //$orderNo = '';
+        $pp = new PayPal($conf);
+        $flag = $pp->executePayment($paymentId);
+        if ($flag) {
+            $orderModel = new PaySuccess($orderNo);
+            $status = $orderModel->onPaySuccess(OrderPayTypeEnum::PAYPAL, ['transaction_id' => $paymentId]);
+            if (!$status) {
+               return $this->renderError('Something Wrong!');
+            }
+
+        }
+        return $this->renderSuccess([], 'Successful!');
+    }
+
+    /**
      * 获取结算台验证器
      * @return CheckoutValidate
      */

+ 3 - 0
app/api/service/Cart.php

@@ -40,6 +40,9 @@ class Cart extends BaseService
     {
         // 购物车列表
         $cartList = $this->getCartList($cartIds);
+        if ($cartList->isEmpty()){
+            return [];
+        }
         // 整理商品ID集
         $goodsIds = helper::getArrayColumn($cartList, 'goods_id');
         if (empty($goodsIds)) return [];

+ 2 - 7
app/api/service/Payment.php

@@ -50,16 +50,11 @@ class Payment extends BaseService
         }
 
         if ($payType == OrderPayTypeEnum::PAYPAL) {
-            $conf = [
-                'client_id' => 'AS0FH780ZGtSAdpT1NTjwkFzryCPf69rZb_FR9Rt_rZdasB80cmjqTQ6CQELWiFVh_MU9e31CSnyz7Ai',     // ClientID
-                'secret' => 'EDqRQhgLNHCb5bxld98T8-JJJZKvMIeqxudO7lMwDFOxBfy138PjM5A21FnDNyb3q4yYUh8r7Qr2BnVi',      // ClientSecret
-                'web_hook_id' => '3NP026061E6858914'
-            ];
-
+            $conf = config('paypal');
             $pp = new PayPal($conf);
             return $pp->unify($order['order_no'], $order['pay_price']);
-
         }
+        //todo stripe
         return [];
     }
 

+ 2 - 0
app/api/service/order/Checkout.php

@@ -26,6 +26,7 @@ use app\api\service\coupon\GoodsDeduct as GoodsDeductService;
 use app\api\service\points\GoodsDeduct as PointsDeductService;
 use app\api\service\order\source\checkout\Factory as CheckoutFactory;
 
+use app\common\enum\order\PayStatus as PayStatusEnum;
 use app\common\enum\Setting as SettingEnum;
 use app\common\enum\order\PayType as OrderPayTypeEnum;
 use app\common\enum\order\OrderStatus as OrderStatusEnum;
@@ -759,6 +760,7 @@ class Checkout extends BaseService
             'pay_price' => $order['orderPayPrice'],
             'delivery_type' => $order['delivery'],
             'pay_type' => $order['payType'],
+            'pay_status' => PayStatusEnum::PENDING,
             'buyer_remark' => trim($remark),
             'order_source' => $this->orderSource['source'],
             'order_source_id' => $this->orderSource['source_id'],

+ 26 - 52
app/common/library/paypal/PayPal.php

@@ -90,8 +90,8 @@ class PayPal
     {
         $apiContext = new ApiContext(
             new OAuthTokenCredential(
-                'AS0FH780ZGtSAdpT1NTjwkFzryCPf69rZb_FR9Rt_rZdasB80cmjqTQ6CQELWiFVh_MU9e31CSnyz7Ai',     // ClientID
-                'EDqRQhgLNHCb5bxld98T8-JJJZKvMIeqxudO7lMwDFOxBfy138PjM5A21FnDNyb3q4yYUh8r7Qr2BnVi'      // ClientSecret
+                $this->config['client_id'],     // ClientID
+                $this->config['secret']      // ClientSecret
             )
         );
 
@@ -107,8 +107,15 @@ class PayPal
         $transaction->setAmount($amount);
 
         $redirectUrls = new RedirectUrls();
-        $redirectUrls->setReturnUrl("https://lar.lmm.gold/api/index/index")
-            ->setCancelUrl("https://lar.lmm.gold/store/index.html");
+        //live
+        //$return_url = config('app.app_host') . $this->config['return_url'] . $outTradeNo;
+        //$cancel_Url = config('app.app_host').$this->config['cancel_url'];
+        //sandbox
+        $return_url = 'https://lar.lmm.gold/api/index/index';
+        $cancel_url = 'https://lar.lmm.gold/store/index.html';
+
+        $redirectUrls->setReturnUrl($return_url)
+            ->setCancelUrl($cancel_url);
 
         $payment = new Payment();
         $payment->setIntent('sale')
@@ -116,21 +123,10 @@ class PayPal
             ->setTransactions(array($transaction))
             ->setRedirectUrls($redirectUrls);
 
-        //$payment->create($apiContext);
-
-
-            $this->result = $payment->create($apiContext);// This will print the detailed information on the exception.
-            //REALLY HELPFUL FOR DEBUGGING
-//            $this->throwError('支付宝API交易查询失败:' . , true, 'tradeQuery');
-//            return false;
-        echo $this->result;die;
-        echo "\n\nRedirect user to approval_url: " . $payment->getApprovalLink() . "\n";
-        // 记录日志
-        Log::append('PayPal-unify', ['result' => $this->result]);
-        return ['approval_link'=>$payment->getApprovalLink()];
-        redirect($payment->getApprovalLink());
-        // 请求成功
-        return true;
+        $this->result = $payment->create($apiContext);// This will print the detailed information on the exception.
+        //REALLY HELPFUL FOR DEBUGGING
+        //echo "\n\nRedirect user to approval_url: " . $payment->getApprovalLink() . "\n";
+        return ['approval_link' => $payment->getApprovalLink()];
     }
 
     /**
@@ -143,7 +139,7 @@ class PayPal
     {
         try {
 
-            $result = Order::get($outTradeNo, $this->apiContext);
+            $payment = Payment::get($outTradeNo, $this->apiContext);
             // 记录日志
             Log::append('Paypal-tradeQuery', ['outTradeNo' => $outTradeNo, 'result' => json_encode($result)]);
             // 处理响应或异常
@@ -165,7 +161,14 @@ class PayPal
 
             // 执行付款
             $payment->execute($execution, $this->apiContext);
-            return $payment::get($payment->getId(), $this->apiContext);
+            $payment::get($payment->getId(), $this->apiContext);
+            $transactions = $payment->getTransactions();
+            \think\facade\Log::error('$transactions::' . json_encode($transactions));
+            if ($payment->getState() == 'approved' && $payment->getId() == $paymentId) {
+                //related_resources->sale->id
+                return true;
+            }
+            return false;
 
         } catch (\Exception $e) {
             \think\facade\Log::error('executePayment', ['paymentId' => $paymentId, 'errMsg' => $e->getMessage()]);
@@ -213,16 +216,6 @@ class PayPal
             \think\facade\Log::error('PayPal Notification Verify Failed' . $exception->getMessage());
             return false;
         }
-
-        // 记录日志
-//        Log::append('PayPal-notify', [
-//            'params' => $this->notifyParams,
-//            'verifyNotify' => $verifyNotify,
-//            'response' => $this->getNotifyResponse(),
-//            'result' => $this->notifyResult,
-//            'message' => '支付宝异步回调验证' . ($this->notifyResult ? '成功' : '失败')
-//        ]);
-        return $this->notifyResult;
     }
 
     /**
@@ -255,7 +248,6 @@ class PayPal
      */
     public function transfers(string $outTradeNo, string $totalFee, array $extra = []): bool
     {
-        // https://opendocs.alipay.com/apis/api_28/alipay.fund.trans.uni.transfer
         return false;
     }
 
@@ -299,8 +291,6 @@ class PayPal
      */
     public function setOptions(array $options, string $client)
     {
-
-
         return $this;
     }
 
@@ -326,28 +316,12 @@ class PayPal
      */
     private function extraAsUnify(array $extra): array
     {
-        if ($this->client === ClientEnum::H5) {
-            if (!array_key_exists('returnUrl', $extra)) {
-                $this->throwError('returnUrl参数不存在');
-            }
+        if (!array_key_exists('returnUrl', $extra)) {
+            $this->throwError('returnUrl参数不存在');
         }
         return $extra;
     }
 
-    /**
-     * 删除HTML中的指定标签
-     * @param array $tags
-     * @param $string
-     * @return array|string|string[]|null
-     */
-    private function deleteHtmlTags(array $tags, $string)
-    {
-        $preg = [];
-        foreach ($tags as $key => $value) {
-            $preg[$key] = "/<({$value}.*?)>(.*?)<(\/{$value}.*?)>/si";
-        }
-        return preg_replace($preg, '', $string);
-    }
 
     /**
      * 异步回调地址

+ 1 - 1
config/app.php

@@ -9,7 +9,7 @@ return [
     // 应用的命名空间
     'app_namespace'    => '',
     // 是否启用路由
-    'with_route'       => false,
+    'with_route'       => true,
     // 是否启用事件
     'with_event'       => true,
     // 默认应用

+ 9 - 0
config/paypal.php

@@ -0,0 +1,9 @@
+<?php
+return [
+    'mode' => 'sandbox',//live,sandbox
+    'web_hook_id' => '3NP026061E6858914',
+    'client_id' => 'AS0FH780ZGtSAdpT1NTjwkFzryCPf69rZb_FR9Rt_rZdasB80cmjqTQ6CQELWiFVh_MU9e31CSnyz7Ai',
+    'secret' => 'EDqRQhgLNHCb5bxld98T8-JJJZKvMIeqxudO7lMwDFOxBfy138PjM5A21FnDNyb3q4yYUh8r7Qr2BnVi',
+    'return_url' => 'https://lar.lmm.gold/api/index/index',//vp.com/index.php/api/checkout/payPayExecutePay/orderNo/9999
+    'cancel_url' => 'https://lar.lmm.gold/store/index.html',
+];

+ 1 - 1
config/route.php

@@ -20,7 +20,7 @@ return [
     // pathinfo分隔符
     'pathinfo_depr'         => '/',
     // URL伪静态后缀
-    'url_html_suffix'       => '',
+    'url_html_suffix'       => 'html',
     // URL普通方式参数 用于自动生成
     'url_common_param'      => true,
     // 是否开启路由延迟解析