ショコラ
PHP PayPal のアクセストークンを生成するには?
PayPal のアクセストークンを取得するサンプルプログラムです。
cURL ではなく file_get_contents を使用しています。
というか、アクセストークンだけではないですね。こちらのページに PayPal まとめていきます。
元ネタは↓こちらなのです。
https://developer.paypal.com/docs/checkout/standard/integrate/
もっさん先輩
アクセストークンを生成するプログラム
<?php
define('CLIENT_ID','{ペイパルの管理画面のクライアントID}');
define('APP_SECRET','{ペイパルの管理画面のシークレット}');
define('base','https://api-m.sandbox.paypal.com');
function generateAccessToken() {
$url = base.'/v1/oauth2/token';
$auth = base64_encode(CLIENT_ID.':'.APP_SECRET);
$header = [
"Authorization: Basic {$auth}",
];
$context = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n",$header),
'content' => 'grant_type=client_credentials',
'timeout' => 60, //second
],
];
$json = file_get_contents($url,false,stream_context_create($context));
return json_decode($json)?->access_token;
}
※sandbox用です。
generateAccessToken関数を実行してみましょう。
echo generateAccessToken();
createOrder関数
function createOrder() {
$accessToken = generateAccessToken();
$url = base.'/v2/checkout/orders';
$header = [
'Content-Type: application/json',
"Authorization: Bearer {$accessToken}",
];
$content = [
'intent' => 'CAPTURE',
'purchase_units' => [
[
'amount' => [
'currency_code' => 'JPY',
'value' => '1100',
],
],
],
];
$context = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n",$header),
'content' => json_encode($content),
'timeout' => 60, //min
],
];
$json = file_get_contents($url,false,stream_context_create($context));
return $json;
}
capturePayment関数
function capturePayment( $orderId ) {
$accessToken = generateAccessToken();
$url = base."/v2/checkout/orders/{$orderId}/capture";
$header = [
'Content-Type: application/json',
"Authorization: Bearer {$accessToken}",
];
$context = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n",$header),
'timeout' => 60, //min
],
];
$json = file_get_contents($url,false,stream_context_create($context));
return $json;
}
まとめると↓こんな感じです。file_get_contents に例外処理を追加して post関数 にまとめました。
<?php
define('CLIENT_ID','{ペイパルの管理画面のクライアントID}');
define('APP_SECRET','{ペイパルの管理画面のシークレット}');
define('base','https://api-m.sandbox.paypal.com');
function post($url,$context) {
$result = file_get_contents($url,false,stream_context_create($context));
$status = $http_response_header[0] ?? '';
if (!(str_contains($status,'200 OK') || str_contains($status,'201 Created'))) {
throw new Exception($status);
}
return $result;
}
function generateAccessToken() {
$url = base.'/v1/oauth2/token';
$auth = base64_encode(CLIENT_ID.':'.APP_SECRET);
$header = [
"Authorization: Basic {$auth}",
];
$context = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n",$header),
'content' => 'grant_type=client_credentials',
'timeout' => 60, //min
],
];
$json = post($url,$context);
return json_decode($json)?->access_token;
}
function createOrder() {
$accessToken = generateAccessToken();
$url = base.'/v2/checkout/orders';
$header = [
'Content-Type: application/json',
"Authorization: Bearer {$accessToken}",
];
$content = [
'intent' => 'CAPTURE',
'purchase_units' => [
[
'amount' => [
'currency_code' => 'JPY',
'value' => '1100',
],
],
],
];
$context = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n",$header),
'content' => json_encode($content),
'timeout' => 60, //min
],
];
$json = post($url,$context);
return $json;
}
function capturePayment( $orderID ) {
$accessToken = generateAccessToken();
$url = base."/v2/checkout/orders/{$orderID}/capture";
$header = [
'Content-Type: application/json',
"Authorization: Bearer {$accessToken}",
];
$context = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n",$header),
'timeout' => 60, //min
],
];
$json = post($url,$context);
return $json;
}
パラメーターで createOrder と capturePayment を処理するようにしました。
<?php
include "paypal-api.php";
if (isset($_GET['createOrder'])) {
header('Content-Type: application/json');
echo createOrder();
}
if (isset($_GET['capturePayment'])) {
header('Content-Type: application/json');
$body = file_get_contents('php://input');
$req = json_decode($body);
echo capturePayment( $req->orderID );
}
クライアント側の JavaScript はこんな感じですね。
<!-- Replace "test" with your own sandbox Business account app client ID -->
<script src="https://www.paypal.com/sdk/js?client-id={ペイパルの管理画面のクライアントID}¤cy=JPY"></script>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<script>
paypal.Buttons({
// Order is created on the server and the order id is returned
createOrder() {
return fetch("/my-server/create-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
// use the "body" param to optionally pass additional order information
// like product skus and quantities
body: JSON.stringify({
cart: [
{
sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
}),
})
.then((response) => response.json())
.then((order) => order.id);
},
// Finalize the transaction on the server after payer approval
onApprove(data) {
return fetch("/my-server/capture-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
orderID: data.orderID
})
})
.then((response) => response.json())
.then((orderData) => {
// Successful capture! For dev/demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
const transaction = orderData.purchase_units[0].payments.captures[0];
alert(`Transaction ${transaction.status}: ${transaction.id}\n\nSee console for all available details`);
// When ready to go live, remove the alert and show a success message within this page. For example:
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: window.location.href = 'thank_you.html';
});
}
}).render('#paypal-button-container');
</script>
注文情報取得
注文を取得する関数はこちらです。キーを注文番号にしてますけど、これでいいのかな?
※orderID は「取引ID」ではありません。取得方法も不明。注文時のIDを保存しておくしかない?
function getOrder( $orderID ) {
$accessToken = generateAccessToken();
$url = base.'/v2/checkout/orders/'.$orderID;
$header = [
"Authorization: Bearer {$accessToken}",
];
$context = [
'http' => [
'method' => 'GET',
'header' => implode("\r\n",$header),
'timeout' => 60, //min
],
];
$json = post($url,$context);
return $json;
}
CAPTURE
CAPTURE の明細をする例です。
$content = [
'intent' => 'CAPTURE',
'purchase_units' => [
[
'items' => [
[
'name' => '{商品名}',
'quantity' => '{注文個数}',
'sku' => '{商品SKU}',
'unit_amount' => ['currency_code'=>'JPY','value'=>{商品価格}],
'tax' => ['currency_code'=>'JPY','value'=>{商品消費税}],
],
],
'amount' => [
'currency_code' => 'JPY',
'value' => $bsk_cnf['pay_all'],
'breakdown' => [
'item_total' => ['currency_code'=>'JPY','value'=>{商品小計}],
'tax_total' => ['currency_code'=>'JPY','value'=>{消費税}],
'discount' => ['currency_code'=>'JPY','value'=>{値引き}],
'shipping' => ['currency_code'=>'JPY','value'=>{送料}],
],
],
],
],
];
以上