クラス
Client
ソース ソース
ファイル: src/Api/Client.php
class Client
{
const REQUEST_API = '/request';
const CONFIRM_API = '/confirm';
const CAPTURE_API = '/capture';
const VOID_API = '/void';
const REFUND_API = '/refund';
const CHECK_API = '/check';
/**
* LINE Pay module object
*
* @var LinePay
*/
private $module;
/**
* Guzzle client
*
* @var \GuzzleHttp\Client
*/
protected $guzzle;
/**
* LINE Pay channel_id
*
* @var string
*/
private $channelid;
/**
* LINE Pay channel_secret
*
* @var string
*/
private $secret;
/**
* Set to true if request is being sent by an admin to get more
* detailed error responses
*
* @var boolean
*/
public $adminreq = false;
/**
* Initialize Guzzle client
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param LinePay $module
* @param string $endpoint
* @param string $channelid
* @param string $secret
*/
public function __construct(LinePay $module, $endpoint, $channelid, $secret) {
$this->module = $module;
$this->channelid = $channelid;
$this->secret = $secret;
$this->guzzle = new GuzzleHttp\Client([
'base_uri' => $endpoint . Constants::API_VERSION_ROUTE,
'headers' => [
'Content-Type' => 'application/json',
'X-LINE-ChannelId' => $this->channelid,
],
]);
}
/**
* Signs a request and returns headers
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param string $uri
* @param string $payload
* @return array
*/
private function getRequestAuthHeaders($uri, $payload = '') {
$nonce = gmdate('c');
$data = $this->secret . $uri . $payload . $nonce;
$signature = base64_encode(hash_hmac('sha256', $data, $this->secret, true));
return [
'X-LINE-Authorization' => $signature,
'X-LINE-Authorization-Nonce' => $nonce,
];
}
/**
* Request dispatcher/handler
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param function $req
* @param string|null $transactionId
* @param string|null $orderid LINE Pay order_id
* @return array|LinePayError
*/
private function sendRequest($req, $transactionId = null, $orderid = null) {
try {
$response = $req();
$res = json_decode($response->getBody(), true);
$code = $res['returnCode'];
$returnMessage = $res['returnMessage'];
if ($code === '0000') {
return $res;
}
$estore = $this->module->adminErrorStore;
if ($this->adminreq === false) {
$estore = $this->module->clientErrorStore;
}
$emap = $estore->getErrorCodeMap();
if (!isset($emap[$code])) {
return $estore->getDefaultErrorObject($code);
}
$meta = $emap[$code];
http_response_code($meta->httpcode);
$error = new LinePayError(
$meta->errorcode,
$meta->errorname,
$meta->httpcode,
is_callable($meta->debugmsg) ? call_user_func($meta->debugmsg, $returnMessage) : $meta->debugmsg,
is_callable($meta->message) ? call_user_func($meta->message, $returnMessage) : $meta->message,
is_callable($meta->adminmsg) ? call_user_func($meta->adminmsg, $returnMessage) : $meta->adminmsg,
$meta->logger
);
$error->transactionId = $transactionId;
$error->orderId = $orderid;
if ($meta->logger !== null) {
$meta->logger->error($error);
}
return $error;
} catch (Exception $e) {
$meta = $this->module->clientErrorStore->getErrorCodeMap()[ClientErrorStore::NETWORK_ERROR];
http_response_code($meta->httpcode);
$error = new LinePayError(
$meta->errorcode,
$meta->errorname,
$meta->httpcode,
call_user_func($meta->debugmsg, $e->getMessage()),
$meta->message,
$meta->adminmsg,
$meta->logger
);
$error->transactionId = $transactionId;
$error->orderId = $orderid;
$meta->logger->error($error);
return $error;
}
}
/**
* Reserve a payment with LINE Pay
*
* POST `/v3/payments/request`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param array $payload
* @return array|LinePayError
*/
public function reserve($payload) {
return $this->sendRequest(function () use ($payload) {
$uri = Constants::API_VERSION_ROUTE . self::REQUEST_API;
return $this->guzzle->post($uri, [
'json' => $payload,
'headers' => $this->getRequestAuthHeaders($uri, json_encode($payload)),
]);
});
}
/**
* Confirm a payment with LINE Pay
*
* POST `/v3/payments/{transactionId}/confirm`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param array $payload
* @param string $transactionId
* @return array|LinePayError
*/
public function confirm($payload, $transactionId) {
return $this->sendRequest(
function () use ($payload, $transactionId) {
$uri = Constants::API_VERSION_ROUTE . '/' . $transactionId . self::CONFIRM_API;
return $this->guzzle->post($uri, [
'json' => $payload,
'headers' => $this->getRequestAuthHeaders($uri, json_encode($payload)),
]);
},
$transactionId
);
}
/**
* Capture payments from a transaction created by the Request API with capture set
* to false (ie. items that require shipping and aren't charged immediately)
*
* POST `/v3/payments/authorizations/{transactionId}/capture`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param array $payload
* @param string $transactionId
* @return array|LinePayError
*/
public function capture($payload, $transactionId) {
return $this->sendRequest(
function () use ($payload, $transactionId) {
$uri = Constants::API_VERSION_ROUTE . '/authorizations/' . $transactionId . self::CAPTURE_API;
return $this->guzzle->post($uri, [
'json' => $payload,
'headers' => $this->getRequestAuthHeaders($uri, json_encode($payload)),
]);
},
$transactionId
);
}
/**
* Void (cancel) an order that is awaiting capture
*
* POST `/v3/payments/authorizations/{transactionId}/void`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param string $transactionId
* @return array|LinePayError
*/
public function void($transactionId) {
return $this->sendRequest(
function () use ($transactionId) {
$uri = Constants::API_VERSION_ROUTE . '/authorizations/' . $transactionId . self::VOID_API;
return $this->guzzle->post($uri, [
'headers' => $this->getRequestAuthHeaders($uri, ''),
]);
},
$transactionId
);
}
/**
* Refund an order that has been captured
*
* POST `/v3/payments/{transactionId}/refund`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param string $transactionId
* @param array $payload
* @return array|LinePayError
*/
public function refund($transactionId, $payload = '') {
$res = $this->sendRequest(
function () use ($transactionId, $payload) {
$uri = Constants::API_VERSION_ROUTE . '/' . $transactionId . self::REFUND_API;
$opts = [
'headers' => $this->getRequestAuthHeaders($uri, $payload),
];
if (!empty($payload)) {
$opts['json'] = $payload;
}
return $this->guzzle->post($uri, $opts);
},
$transactionId
);
if ($res instanceof GenericError) {
if ($res->errorcode === 1155) {
$error = $this->module->adminErrorStore->getRefund1155Error();
$error->transactionId = $transactionId;
$error->logger->error($error);
}
}
return $res;
}
/**
* Check payment status of a LINE Pay transaction
*
* GET `/v3/payments/requests/{transactionId}/check`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param string $transactionId
* @return array|LinePayError
*/
public function check($transactionId) {
return $this->sendRequest(
function () use ($transactionId) {
$uri = Constants::API_VERSION_ROUTE . '/requests/' . $transactionId . self::CHECK_API;
return $this->guzzle->get($uri, [
'headers' => $this->getRequestAuthHeaders($uri),
]);
},
$transactionId
);
}
/**
* Check payment(s) status(es)
*
* GET `/v3/payments`
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param array $payload transactionId[]
* @return array|LinePayError
*/
public function payments($payload) {
return $this->sendRequest(
function () use ($payload) {
$query = http_build_query($payload);
$uri = Constants::API_VERSION_ROUTE . '?' . $query;
return $this->guzzle->get($uri, [
'headers' => $this->getRequestAuthHeaders(Constants::API_VERSION_ROUTE, $query),
]);
}
);
}
}
- __construct — Initialize Guzzle client
- capture — Capture payments from a transaction created by the Request API with capture set to false (ie. items that require shipping and aren't charged immediately)
- check — Check payment status of a LINE Pay transaction
- confirm — Confirm a payment with LINE Pay
- getRequestAuthHeaders — Signs a request and returns headers
- payments — Check payment(s) status(es)
- refund — Refund an order that has been captured
- reserve — Reserve a payment with LINE Pay
- sendRequest — Request dispatcher/handler
- void — Void (cancel) an order that is awaiting capture