クラス
Request
ソース ソース
ファイル: src/Api/Request.php
class Request
{
/**
* Name3 from SESSION if set or POST
*
* @var string
*/
public $name3;
/**
* Name4 from SESSION if set or POST
*
* @var string
*/
public $name4;
/**
* Settlement module
*
* @var LinePay
*/
private $module;
/**
* Inject `LinePay` module
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param LinePay $module
*/
public function __construct(LinePay $module) {
$this->module = $module;
}
/**
* Returns error if name3 and name4 are not set in SESSION and not set in POST
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @return Closure&#Function#850928c3
*/
public function furiganaCheckMiddleware() {
return function ($args, $payload) {
if (usces_have_shipped() === false) {
return;
}
$del = $_SESSION['usces_entry']['delivery'];
if (strtoupper($del['country']) === 'JP') {
$name3 = isset($del['name3']) ? $del['name3'] : '';
$name4 = isset($del['name4']) ? $del['name4'] : '';
$this->name3 = $name3;
$this->name4 = $name4;
if (empty($name3) || empty($name4)) {
if (empty($payload) || !isset($payload)) {
return $this->module->clientErrorStore->getErrorResponse(ErrorCodes::FURIGANA_NAMES_REQUIRED);
}
$input_name3 = isset($payload['name3']) ? $payload['name3'] : '';
$input_name4 = isset($payload['name4']) ? $payload['name4'] : '';
if (empty($input_name3) || empty($input_name4)) {
return $this->module->clientErrorStore->getErrorResponse(ErrorCodes::FURIGANA_NAMES_REQUIRED);
}
// we set our member variables here because updating $_SESSION directly
// causes an automatic redirect to the cart page :/
$this->name3 = $input_name3;
$this->name4 = $input_name4;
}
}
};
}
/**
* Returns error if total price is 0 or less
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @return Closure&#Function#850928c2
*/
public function checkTotalPriceMiddleware() {
return function () {
if ($_SESSION['usces_entry']['order']['total_full_price'] <= 0) {
return $this->module->clientErrorStore->getErrorResponse(ErrorCodes::AMOUNT_IS_ZERO);
}
};
}
/**
* Create a transaction
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @global \usc_e_shop $usces
* @return array
*/
public function request() {
global $usces;
$entry = isset($_SESSION['usces_entry']) ? $_SESSION['usces_entry'] : [];
$order = !empty($entry['order']) ? $entry['order'] : [];
if (empty($entry) || empty($order)) {
return $this->module->clientErrorStore->getErrorResponse(ClientErrorStore::INTERNAL_SERVER_ERROR);
}
$payload = $this->makeRequestBody();
$payload = $this->calculateItemPrices($payload);
$res = $this->module->api->reserve($payload);
if ($res instanceof GenericError) {
return $res;
}
// add SESSION data of transaction to database for fulfillment on LINE redirect
add_option(
$res['info']['transactionId'],
[
'acting' => $this->module->getActing(),
'line_request_res' => $res,
'total' => $order['total_full_price'],
'currency' => strtoupper(usces_crcode('return')),
'capture_now' => $payload['options']['payment']['capture'],
'usces_cart' => $usces->cart->get_cart(),
'usces_entry' => isset($_SESSION['usces_entry']) ? $_SESSION['usces_entry'] : [],
'usces_member' => isset($_SESSION['usces_member']) ? $_SESSION['usces_member'] : [],
]
);
// save order data preprocessing
usces_save_order_acting_data($res['info']['transactionId']);
return $res;
}
/**
* Make request body from SESSION data
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @global \usc_e_shop $usces
* @return array
*/
public function makeRequestBody() {
global $usces;
$order = $_SESSION['usces_entry']['order'];
$delivery = isset($_SESSION['usces_entry']['delivery']) ? $_SESSION['usces_entry']['delivery'] : [];
$products = [];
$index = 0;
$shipping = false;
$capture_type = $this->module->getActingOpts()['payment_capture_type'];
$capture = $capture_type === 'on_purchase' ? true : false;
$cart = $usces->cart->get_cart();
foreach ($cart as $item) {
$item_division = get_post_meta($item['post_id'], '_item_division', true);
$division = empty($item_division) ? 'shipped' : $item_division;
if ($division === 'shipped') {
$shipping = true;
}
$itemCode = $usces->getItemCode($item['post_id']);
$pictid = (int)$usces->get_mainpictid($itemCode);
$imageurl = wp_get_attachment_image_src($pictid);
$products[] = [
'id' => $itemCode,
'name' => $usces->getItemName($item['post_id']),
'quantity' => $item['quantity'],
'price' => $item['price'],
];
if ($imageurl !== false) {
$products[$index]['imageUrl'] = $imageurl[0];
}
$index++;
}
$packages = [
'id' => uniqid(),
'amount' => $order['total_items_price'],
'userFee' => 0,
'products' => $products,
];
$cname = get_option('usces')['company_name'];
if (!empty($cname)) {
$packages['name'] = $cname;
}
$uuid = uniqid('wcexalp_request_', true);
$payload = [
'amount' => $order['total_full_price'],
'currency' => strtoupper(usces_crcode('return')),
'orderId' => $uuid,
'redirectUrls' => [
'cancelUrl' => USCES_CART_URL,
'confirmUrl' => LinePay::getConfirmRedirectUrl(),
'confirmUrlType' => 'CLIENT',
],
'packages' => [$packages],
'options' => [
'display' => [
'locale' => $this->module->getActingOpts()['locale'],
],
'payment' => [
'capture' => $capture,
],
],
];
if ($shipping === true) {
$payload['options']['shipping'] = [
'feeAmount' => $order['shipping_charge'],
'type' => 'FIXED_ADDRESS',
'feeInquiryType' => 'FIXED',
'address' => [
'country' => $delivery['country'],
'postalCode' => $delivery['zipcode'],
'state' => $delivery['pref'],
'city' => $delivery['address1'],
'detail' => $delivery['address2'],
'optional' => $delivery['address3'],
'recipient' => [
'firstName' => $delivery['name2'],
'lastName' => $delivery['name1'],
'firstNameOptional' => $this->name4,
'lastNameOptional' => $this->name3,
'email' => $delivery['mailaddress1'],
'phoneNo' => $delivery['tel'],
],
],
];
}
return $payload;
}
/**
* Apply discount, point usage, coupon usage, and tax as dummy products.
*
* LINE Pay has no fields for any of the above listed, and yet the total_full_price **MUST**
* equal the total_items_price + shipping_fee or /v3/payments/request will fail.
*
* Therefore, we have to create fake products that represent discounts and other fees
*
* Apparently the great mighty LINE didn't anticipate any of this... What a shocker...
*
* @author Evan D Shaw <evandanielshaw@gmail.com>
* @param array $payload
* @return array
*/
public function calculateItemPrices($payload) {
$order = $_SESSION['usces_entry']['order'];
$usedpoint = $order['usedpoint'] * -1;
$im_a_teapot = $usedpoint + $order['discount'] + $order['tax'];
if ($order['discount'] !== 0) {
$payload['packages'][0]['products'][] = [
'name' => __('Discount', 'wcex_linepay'),
'quantity' => 1,
'price' => $order['discount'],
];
}
if (get_option('usces')['tax_mode'] === 'exclude' && $order['tax'] > 0) {
$payload['packages'][0]['products'][] = [
'name' => __('consumption tax', 'usces'),
'quantity' => 1,
'price' => $order['tax'],
];
}
if ($order['usedpoint'] > 0) {
$payload['packages'][0]['products'][] = [
'name' => __('Used points', 'usces'),
'quantity' => 1,
'price' => $usedpoint,
];
}
$payload['packages'][0]['amount'] = $payload['packages'][0]['amount'] + $im_a_teapot;
return $payload;
}
}
- __construct — Inject `LinePay` module
- calculateItemPrices — Apply discount, point usage, coupon usage, and tax as dummy products.
- checkTotalPriceMiddleware — Returns error if total price is 0 or less
- furiganaCheckMiddleware — Returns error if name3 and name4 are not set in SESSION and not set in POST
- makeRequestBody — Make request body from SESSION data
- request — Create a transaction