PaypalPayment.php
4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
/**
* Created by PhpStorm.
* User: lishuai
* Date: 2022/2/15
* Time: 4:23 PM
*/
namespace App\Payment;
use App\Models\Order;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Redis;
class PaypalPayment implements PaymentInterface
{
const IS_SANDBOX = true;
public $baseUrl = 'https://api-m.paypal.com';
public $baseUrlSandbox = 'https://api-m.sandbox.paypal.com';
public $clientId = 'AdDRE91WSp5q1fYLODpJduc2mRjA_v6E205SvkfVSOgvr98xLeyDCHY4OPAaSFMK1SHYOfJ4TksHSX1-';
public $secret = 'EDoy_PVrFyobWt9DzAMRMikJwWCXenkWSx9CGFz0MxHt3a8fs6v-LnORMilIbftb2GwBKxOoTVZNBHNR';
/** 访问令牌*/
public $accessToken;
public function __construct()
{
// 初始化时做一些准备工作
$redis = Redis::connection();
$access_token = $redis->get('paypal:access_token');
if ($access_token){
$this->accessToken = $access_token;
}else{
$client = new Client([
'base_uri' => $this->baseUrlSandbox,
'headers'=>[
'Content-Type' => 'application/x-www-form-urlencoded',
'Accept'=>'application/json',
]
]);
$response = $client->post('/v1/oauth2/token',[
'form_params'=>['grant_type' => 'client_credentials'],
'auth' => [$this->clientId, $this->secret],
]);
$body = $response->getBody();
$content = json_decode($body->getContents(),true);
$this->accessToken = $content['access_token'];
$redis->setex('paypal:access_token',$content['expires_in'],$content['access_token']);
}
}
/**
* Setting up the JSON request body for creating the Order. The Intent in the
* request body should be set as "CAPTURE" for capture intent flow.
* @param Order $order
* @return array
*/
private static function buildCreateOrderRequestBody(Order $order)
{
return array(
'intent' => 'CAPTURE', //CAPTURE 商家打算在客户付款后立即扣款。 AUTHORIZE 商家打算在客户付款后授权付款并暂停资金
'application_context' =>
array(
'return_url' => 'https://example.com/return', // todo
'cancel_url' => 'https://example.com/cancel', // todo 这里要询问reason app是否有schema,
'brand_name' => 'Parlando', //覆盖 PayPal 网站上 PayPal 帐户中公司名称的标签。
'locale' => 'en-US', //zh-CN
'landing_page' => 'NO_PREFERENCE', //LOGIN / BILLING / NO_PREFERENCE
'shipping_preference' => 'NO_SHIPPING', //运输偏好
'user_action' => 'PAY_NOW',
),
'purchase_units' =>
array(
0 =>
array(
'description' => $order->description, // 购买说明
'custom_id' => $order->order_sn, //API 调用者提供的外部 ID 可以理解为order_id osnxxxxxx
'soft_descriptor' => 'PayPal Parlando Vip', // 出现在付款人卡对帐单上的对帐单描述符的动态文本 最大长度:22.
'amount' =>
array(
'currency_code' => 'USD', // CNY
'value' => $order->pay_amount, //
),
),
),
);
}
public function prepare(Order $order)
{
// 在PayPal上创建一个订单,它会返回一个订单对象,它有一个订单id
$client = new Client([
'base_uri' => $this->baseUrlSandbox,
'headers'=>[
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->accessToken,
'Prefer' => 'return=representation',
]
]);
$response = $client->post('/v2/checkout/orders',[
'json' => self::buildCreateOrderRequestBody($order),
]);
$body = $response->getBody();
$content = json_decode($body->getContents(),true);
return $content;
}
public function capture($orderId)
{
$client = new Client([
'base_uri' => $this->baseUrlSandbox,
'headers'=>[
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->accessToken,
'Prefer' => 'return=representation',
]
]);
$response = $client->post('/v2/checkout/orders/' . $orderId . '/capture');
$body = $response->getBody();
$content = json_decode($body->getContents(),true);
// todo 应该使用队列,异步执行回调程序
return $content;
}
public function notify()
{
}
}