Showing
3 changed files
with
94 additions
and
9 deletions
... | @@ -73,6 +73,8 @@ class OrderController extends Controller | ... | @@ -73,6 +73,8 @@ class OrderController extends Controller |
73 | return DB::transaction(function ()use ($user_id, $member_id, $source, $number){ | 73 | return DB::transaction(function ()use ($user_id, $member_id, $source, $number){ |
74 | // 获取商品信息 | 74 | // 获取商品信息 |
75 | $membership_good = MembershipGood::query()->where('id',$member_id)->first(); | 75 | $membership_good = MembershipGood::query()->where('id',$member_id)->first(); |
76 | + if (!$membership_good) throw new \Exception('没有此商品'); | ||
77 | + | ||
76 | $membership = $membership_good->membership()->first(); | 78 | $membership = $membership_good->membership()->first(); |
77 | 79 | ||
78 | // 实付金额 = 商品金额 | 80 | // 实付金额 = 商品金额 | ... | ... |
... | @@ -37,18 +37,25 @@ class PayController extends Controller | ... | @@ -37,18 +37,25 @@ class PayController extends Controller |
37 | */ | 37 | */ |
38 | public function store(Request $request) | 38 | public function store(Request $request) |
39 | { | 39 | { |
40 | - // | 40 | + // 回调 |
41 | } | 41 | } |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * Display the specified resource. | 44 | * Display the specified resource. |
45 | * | 45 | * |
46 | * @param int $id | 46 | * @param int $id |
47 | - * @return \Illuminate\Http\Response | 47 | + * @param Request $request |
48 | + * @param PaymentFactory $factory | ||
49 | + * @return \Illuminate\Http\JsonResponse | ||
50 | + * @throws \Exception | ||
48 | */ | 51 | */ |
49 | - public function show($id) | 52 | + public function show($id, Request $request, PaymentFactory $factory) |
50 | { | 53 | { |
51 | - // | 54 | + $pay_type = $request->get('pay_type'); |
55 | + | ||
56 | + $capture = $factory->init($pay_type)->capture($id); | ||
57 | + | ||
58 | + return Response::success($capture); | ||
52 | } | 59 | } |
53 | 60 | ||
54 | /** | 61 | /** | ... | ... |
... | @@ -17,11 +17,10 @@ class PaypalPayment implements PaymentInterface | ... | @@ -17,11 +17,10 @@ class PaypalPayment implements PaymentInterface |
17 | 17 | ||
18 | const IS_SANDBOX = true; | 18 | const IS_SANDBOX = true; |
19 | 19 | ||
20 | - public $authUrl = 'https://api-m.sandbox.paypal.com/v1/oauth2/token'; | 20 | + public $baseUrl = 'https://api-m.paypal.com'; |
21 | 21 | ||
22 | - public $paySandboxUrl = 'https://api-m.sandbox.paypal.com'; | 22 | + public $baseUrlSandbox = 'https://api-m.sandbox.paypal.com'; |
23 | 23 | ||
24 | - public $payUrl = 'https://api-m.paypal.com'; | ||
25 | 24 | ||
26 | public $clientId = 'AdDRE91WSp5q1fYLODpJduc2mRjA_v6E205SvkfVSOgvr98xLeyDCHY4OPAaSFMK1SHYOfJ4TksHSX1-'; | 25 | public $clientId = 'AdDRE91WSp5q1fYLODpJduc2mRjA_v6E205SvkfVSOgvr98xLeyDCHY4OPAaSFMK1SHYOfJ4TksHSX1-'; |
27 | public $secret = 'EDoy_PVrFyobWt9DzAMRMikJwWCXenkWSx9CGFz0MxHt3a8fs6v-LnORMilIbftb2GwBKxOoTVZNBHNR'; | 26 | public $secret = 'EDoy_PVrFyobWt9DzAMRMikJwWCXenkWSx9CGFz0MxHt3a8fs6v-LnORMilIbftb2GwBKxOoTVZNBHNR'; |
... | @@ -38,13 +37,14 @@ class PaypalPayment implements PaymentInterface | ... | @@ -38,13 +37,14 @@ class PaypalPayment implements PaymentInterface |
38 | $this->accessToken = $access_token; | 37 | $this->accessToken = $access_token; |
39 | }else{ | 38 | }else{ |
40 | $client = new Client([ | 39 | $client = new Client([ |
40 | + 'base_uri' => $this->baseUrlSandbox, | ||
41 | 'headers'=>[ | 41 | 'headers'=>[ |
42 | 'Content-Type' => 'application/x-www-form-urlencoded', | 42 | 'Content-Type' => 'application/x-www-form-urlencoded', |
43 | 'Accept'=>'application/json', | 43 | 'Accept'=>'application/json', |
44 | ] | 44 | ] |
45 | ]); | 45 | ]); |
46 | 46 | ||
47 | - $response = $client->post($this->authUrl,[ | 47 | + $response = $client->post('/v1/oauth2/token',[ |
48 | 'form_params'=>['grant_type' => 'client_credentials'], | 48 | 'form_params'=>['grant_type' => 'client_credentials'], |
49 | 'auth' => [$this->clientId, $this->secret], | 49 | 'auth' => [$this->clientId, $this->secret], |
50 | ]); | 50 | ]); |
... | @@ -56,11 +56,87 @@ class PaypalPayment implements PaymentInterface | ... | @@ -56,11 +56,87 @@ class PaypalPayment implements PaymentInterface |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | + /** | ||
60 | + * Setting up the JSON request body for creating the Order. The Intent in the | ||
61 | + * request body should be set as "CAPTURE" for capture intent flow. | ||
62 | + * @param Order $order | ||
63 | + * @return array | ||
64 | + */ | ||
65 | + private static function buildCreateOrderRequestBody(Order $order) | ||
66 | + { | ||
67 | + return array( | ||
68 | + 'intent' => 'CAPTURE', //CAPTURE 商家打算在客户付款后立即扣款。 AUTHORIZE 商家打算在客户付款后授权付款并暂停资金 | ||
69 | + 'application_context' => | ||
70 | + array( | ||
71 | + 'return_url' => 'https://example.com/return', // todo | ||
72 | + 'cancel_url' => 'https://example.com/cancel', // todo 这里要询问reason app是否有schema, | ||
73 | + 'brand_name' => 'Parlando', //覆盖 PayPal 网站上 PayPal 帐户中公司名称的标签。 | ||
74 | + 'locale' => 'en-US', //zh-CN | ||
75 | + 'landing_page' => 'NO_PREFERENCE', //LOGIN / BILLING / NO_PREFERENCE | ||
76 | + 'shipping_preference' => 'NO_SHIPPING', //运输偏好 | ||
77 | + 'user_action' => 'PAY_NOW', | ||
78 | + ), | ||
79 | + 'purchase_units' => | ||
80 | + array( | ||
81 | + 0 => | ||
82 | + array( | ||
83 | + 'description' => 'Parlando 3 Month Vip', // 购买说明 | ||
84 | + 'custom_id' => 'osnxxxxxx123', //API 调用者提供的外部 ID 可以理解为order_id osnxxxxxx | ||
85 | + 'soft_descriptor' => 'PayPal Parlando Vip', // 出现在付款人卡对帐单上的对帐单描述符的动态文本 最大长度:22. | ||
86 | + 'amount' => | ||
87 | + array( | ||
88 | + 'currency_code' => 'USD', // CNY | ||
89 | + 'value' => '220.00', // | ||
90 | + ), | ||
91 | + ), | ||
92 | + ), | ||
93 | + ); | ||
94 | + } | ||
95 | + | ||
59 | public function prepare(Order $order) | 96 | public function prepare(Order $order) |
60 | { | 97 | { |
61 | // 在PayPal上创建一个订单,它会返回一个订单对象,它有一个订单id | 98 | // 在PayPal上创建一个订单,它会返回一个订单对象,它有一个订单id |
99 | + $client = new Client([ | ||
100 | + 'base_uri' => $this->baseUrlSandbox, | ||
101 | + 'headers'=>[ | ||
102 | + 'Content-Type' => 'application/json', | ||
103 | + 'Authorization' => 'Bearer ' . $this->accessToken, | ||
104 | + 'Prefer' => 'return=representation', | ||
105 | + ] | ||
106 | + ]); | ||
107 | + | ||
108 | + $response = $client->post('/v2/checkout/orders',[ | ||
109 | + 'json' => self::buildCreateOrderRequestBody($order), | ||
110 | + ]); | ||
111 | + $body = $response->getBody(); | ||
112 | + $content = json_decode($body->getContents(),true); | ||
113 | + | ||
114 | + return $content; | ||
115 | + } | ||
62 | 116 | ||
117 | + public function capture($orderId) | ||
118 | + { | ||
119 | + $client = new Client([ | ||
120 | + 'base_uri' => $this->baseUrlSandbox, | ||
121 | + 'headers'=>[ | ||
122 | + 'Content-Type' => 'application/json', | ||
123 | + 'Authorization' => 'Bearer ' . $this->accessToken, | ||
124 | + 'Prefer' => 'return=representation', | ||
125 | + ] | ||
126 | + ]); | ||
127 | + | ||
128 | + $response = $client->post('/v2/checkout/orders/' . $orderId . '/capture'); | ||
129 | + $body = $response->getBody(); | ||
130 | + $content = json_decode($body->getContents(),true); | ||
131 | + | ||
132 | + | ||
133 | + // todo 应该使用队列,异步执行回调程序 | ||
134 | + | ||
135 | + return $content; | ||
136 | + } | ||
137 | + | ||
138 | + public function notify() | ||
139 | + { | ||
63 | 140 | ||
64 | - return $this->accessToken; | ||
65 | } | 141 | } |
66 | } | 142 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment