Add unit and integration tests for collected invoice queue handling, route hardening, lifecycle validation, and manual batch processing logic.
This commit is contained in:
@@ -490,105 +490,121 @@ class ordersRoute
|
||||
);
|
||||
|
||||
$this->post('/orders/module/stripe/payment_intent', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('charge_order');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
// Get the current order
|
||||
$order = (new orders_o())->getOrderById((int)$data['id']);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
// Get the department
|
||||
$department = (new departments_o())->selectId((int)$order->department_id->value());
|
||||
// Check if the department is configured for Stripe payments
|
||||
if (!$department->isStripeConfigured()) {
|
||||
$response->error('Department is not configured for Stripe payments', 400);
|
||||
}
|
||||
// Check if the reader is set
|
||||
if (!isset($data['reader'])) {
|
||||
$response->error('Reader ID is required', 400);
|
||||
}
|
||||
// Get the tax percentage (if any)
|
||||
$tax_percentage = (isset($data['tax_percentage'])) ? (int)$data['tax_percentage'] : null;
|
||||
// Check if the tax percentage is valid
|
||||
if ($tax_percentage !== null && ($tax_percentage < 0 || $tax_percentage > 100)) {
|
||||
$response->error('Invalid tax percentage', 400);
|
||||
}
|
||||
function addTaxNetAmount($net_amount, $tax_percentage): float
|
||||
{
|
||||
// Check if the tax percentage is above 0
|
||||
if (empty($tax_percentage) || $tax_percentage <= 0) {
|
||||
return $net_amount;
|
||||
}
|
||||
return $net_amount + ($net_amount * ($tax_percentage / 100));
|
||||
}
|
||||
|
||||
// Get the Stripe payment intent
|
||||
$stripe = new stripe();
|
||||
$paymentIntent = $stripe->payment_intents->create(
|
||||
addTaxNetAmount(
|
||||
(float)$order->getNetAmount() * 100,
|
||||
$tax_percentage ?? 0
|
||||
),
|
||||
[
|
||||
'description' => 'Order ID: ' . $order->id,
|
||||
'metadata' => [
|
||||
'order_id' => $order->id,
|
||||
'customer_id' => $order->customer_id->value(),
|
||||
'department_id' => $order->department_id->value(),
|
||||
'tax_percentage' => $tax_percentage ?? 0,
|
||||
],
|
||||
'payment_method_types' => ['card_present'],
|
||||
'capture_method' => 'manual',
|
||||
]
|
||||
);
|
||||
// Validate the payment intent
|
||||
try {
|
||||
$stripe->payment_intents->get($paymentIntent->id);
|
||||
} catch (\Stripe\Exception\InvalidRequestException $e) {
|
||||
$response->error('Payment intent not found', 400);
|
||||
}
|
||||
// Set the payment intent ID in the order
|
||||
$stripe_payment_intents = new stripe_payment_intents_o();
|
||||
$stripe_payment_intents->add(
|
||||
(int)$order->id,
|
||||
$paymentIntent->id,
|
||||
$paymentIntent->client_secret,
|
||||
$paymentIntent->toJSON()
|
||||
);
|
||||
|
||||
// Send the payment intent to the reader
|
||||
$stripe->readers->sendPaymentIntent(
|
||||
$data['reader'],
|
||||
$paymentIntent->id,
|
||||
);
|
||||
// Set the reader on the stripe payment intent
|
||||
$stripe_payment_intents->reader_id->set($data['reader']);
|
||||
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'CHARGE_ORDER', 'Successfully charged an order (ID: ' . $data['id'] . ')');
|
||||
|
||||
$response->success([
|
||||
'payment_intent' => $paymentIntent->id,
|
||||
'client_secret' => $paymentIntent->client_secret,
|
||||
]);
|
||||
} else {
|
||||
// Log the incident
|
||||
if (!$user) {
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'CHARGE_ORDER', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
if (!isset($data['id'])) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
|
||||
$order = (new orders_o())->getOrderById((int)$data['id']);
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
|
||||
$department = (new departments_o())->selectId((int)$order->department_id->value());
|
||||
if (!$department->isStripeConfigured()) {
|
||||
$response->error('Department is not configured for Stripe payments', 400);
|
||||
}
|
||||
|
||||
$readerId = trim((string)($data['reader'] ?? ''));
|
||||
if ($readerId === '') {
|
||||
$response->error('Reader ID is required', 400);
|
||||
}
|
||||
|
||||
$tax_percentage = isset($data['tax_percentage']) ? (int)$data['tax_percentage'] : null;
|
||||
if ($tax_percentage !== null && ($tax_percentage < 0 || $tax_percentage > 100)) {
|
||||
$response->error('Invalid tax percentage', 400);
|
||||
}
|
||||
|
||||
$stripe = new stripe();
|
||||
$stripePaymentIntents = new stripe_payment_intents_o();
|
||||
|
||||
if ($stripePaymentIntents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$stripePaymentIntents->selectOrderPaymentIntent((int)$order->id);
|
||||
|
||||
try {
|
||||
$storedPaymentIntent = $stripe->payment_intents->get($stripePaymentIntents->payment_intent_id->value());
|
||||
$stripePaymentIntents->updateStoredPaymentIntent($storedPaymentIntent);
|
||||
$stripePaymentIntents->setReaderId($readerId);
|
||||
if ($tax_percentage !== null) {
|
||||
$stripePaymentIntents->tax_percentage->set($tax_percentage);
|
||||
}
|
||||
|
||||
if ($this->isStripePaymentIntentReusable($storedPaymentIntent)) {
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'CHARGE_ORDER', 'Reused Stripe payment intent for order (ID: ' . $data['id'] . ')');
|
||||
$response->success($this->buildStripePaymentIntentResponse($storedPaymentIntent, $stripePaymentIntents, [
|
||||
'reused' => true,
|
||||
]));
|
||||
}
|
||||
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
}
|
||||
}
|
||||
|
||||
$paymentIntent = $stripe->payment_intents->create(
|
||||
(int)round($this->addTaxNetAmount(
|
||||
(float)$order->getNetAmount() * 100,
|
||||
$tax_percentage ?? 0
|
||||
)),
|
||||
[
|
||||
'description' => 'Order ID: ' . $order->id,
|
||||
'metadata' => [
|
||||
'order_id' => (string)$order->id,
|
||||
'customer_id' => (string)$order->customer_id->value(),
|
||||
'department_id' => (string)$order->department_id->value(),
|
||||
'tax_percentage' => (string)($tax_percentage ?? 0),
|
||||
'reader_id' => $readerId,
|
||||
'reader' => $readerId,
|
||||
],
|
||||
'payment_method_types' => ['card_present'],
|
||||
'capture_method' => 'manual',
|
||||
]
|
||||
);
|
||||
|
||||
$stripePaymentIntents->add(
|
||||
(int)$order->id,
|
||||
$paymentIntent->id,
|
||||
$paymentIntent->client_secret,
|
||||
$paymentIntent->toJSON(),
|
||||
$readerId,
|
||||
$tax_percentage
|
||||
);
|
||||
|
||||
try {
|
||||
$stripe->readers->sendPaymentIntent($readerId, $paymentIntent->id);
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
try {
|
||||
$stripePaymentIntents->delete();
|
||||
} catch (Exception) {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
}
|
||||
$response->error('Unable to start payment on the selected reader', 409);
|
||||
}
|
||||
|
||||
try {
|
||||
$paymentIntent = $stripe->payment_intents->get($paymentIntent->id);
|
||||
$stripePaymentIntents->updateStoredPaymentIntent($paymentIntent);
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
// Keep the created intent payload if Stripe retrieve is temporarily unavailable.
|
||||
}
|
||||
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'CHARGE_ORDER', 'Successfully charged an order (ID: ' . $data['id'] . ')');
|
||||
|
||||
$response->success($this->buildStripePaymentIntentResponse($paymentIntent, $stripePaymentIntents, [
|
||||
'reused' => false,
|
||||
]));
|
||||
},
|
||||
[
|
||||
'charge_order' => 'Charge an order'
|
||||
@@ -596,55 +612,56 @@ class ordersRoute
|
||||
);
|
||||
|
||||
$this->get('/orders/module/stripe/payment_intent', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('get_payment_intent');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
self::requireParameters([
|
||||
'id'
|
||||
]);
|
||||
// Check if the required fields are set
|
||||
$id = self::getParameter('id');
|
||||
if (!isset($id)) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
// Get the current order
|
||||
$order = (new orders_o())->getOrderById((int)$id);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
// Check if the order has a payment intent
|
||||
$stripe_payment_intents = new stripe_payment_intents_o();
|
||||
if (!$stripe_payment_intents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$response->error('Order does not have a payment intent', 400);
|
||||
}
|
||||
$stripe_payment_intents->selectOrderPaymentIntent((int)$order->id);
|
||||
// Get the Stripe payment intent
|
||||
$stripe = new stripe();
|
||||
try {
|
||||
$payment_intent = $stripe->payment_intents->get(
|
||||
$stripe_payment_intents->payment_intent_id->value(),
|
||||
[
|
||||
//'expand' => ['latest_charge'], // This is used to get the latest charge, that can be used to check if the payment has been refunded.
|
||||
]
|
||||
);
|
||||
} catch (\Stripe\Exception\InvalidRequestException $e) {
|
||||
$response->error('Payment intent not found', 400);
|
||||
}
|
||||
$response->success(
|
||||
$payment_intent->toJSON()
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
if (!$user) {
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'GET_PAYMENT_INTENT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
|
||||
self::requireParameters([
|
||||
'id'
|
||||
]);
|
||||
$id = self::getParameter('id');
|
||||
if (!isset($id)) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
|
||||
$order = (new orders_o())->getOrderById((int)$id);
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
|
||||
$stripePaymentIntents = new stripe_payment_intents_o();
|
||||
if (!$stripePaymentIntents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$response->success($this->buildStripePaymentIntentResponse(null, null, [
|
||||
'message' => 'No active payment intent for this order.',
|
||||
]));
|
||||
}
|
||||
|
||||
$stripePaymentIntents->selectOrderPaymentIntent((int)$order->id);
|
||||
$stripe = new stripe();
|
||||
|
||||
try {
|
||||
$paymentIntent = $stripe->payment_intents->get($stripePaymentIntents->payment_intent_id->value());
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
$response->success($this->buildStripePaymentIntentResponse(null, null, [
|
||||
'message' => 'No active payment intent for this order.',
|
||||
]));
|
||||
}
|
||||
|
||||
$status = strtolower((string)($paymentIntent->status ?? ''));
|
||||
if ($status === 'canceled') {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
$response->success($this->buildStripePaymentIntentResponse(null, null, [
|
||||
'message' => 'No active payment intent for this order.',
|
||||
]));
|
||||
}
|
||||
|
||||
$stripePaymentIntents->updateStoredPaymentIntent($paymentIntent);
|
||||
$response->success($this->buildStripePaymentIntentResponse($paymentIntent, $stripePaymentIntents));
|
||||
},
|
||||
[
|
||||
'get_payment_intent' => 'Get a payment intent'
|
||||
@@ -652,45 +669,49 @@ class ordersRoute
|
||||
);
|
||||
|
||||
$this->delete('/orders/module/stripe/payment_intent', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('charge_order');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the data
|
||||
self::requireParameters([
|
||||
'id'
|
||||
]);
|
||||
$id = self::fromRequest('id');
|
||||
// Get the current order
|
||||
$order = (new orders_o())->getOrderById((int)$id);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
// Check if the order has a payment intent
|
||||
$stripe_payment_intents = new stripe_payment_intents_o();
|
||||
if (!$stripe_payment_intents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$response->error('Order does not have a payment intent', 400);
|
||||
}
|
||||
$stripe_payment_intents->selectOrderPaymentIntent((int)$order->id);
|
||||
try {
|
||||
$stripe_payment_intents->delete();
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'DELETE_PAYMENT_INTENT', 'Successfully deleted a payment intent (ID: ' . $id . ')');
|
||||
// Return a success message
|
||||
$response->success(['message' => 'Payment intent deleted successfully']);
|
||||
} catch (\Stripe\Exception\InvalidRequestException $e) {
|
||||
$response->error('Payment intent not found', 400);
|
||||
}
|
||||
} else {
|
||||
// Log the incident
|
||||
if (!$user) {
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'DELETE_PAYMENT_INTENT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
$id = $data['id'] ?? self::fromRequest('id');
|
||||
if (!isset($id)) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
|
||||
$order = (new orders_o())->getOrderById((int)$id);
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
|
||||
$stripePaymentIntents = new stripe_payment_intents_o();
|
||||
if (!$stripePaymentIntents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$response->success($this->buildStripePaymentIntentResponse(null, null, [
|
||||
'message' => 'Payment intent cleared successfully.',
|
||||
'cleared' => true,
|
||||
]));
|
||||
}
|
||||
|
||||
$stripePaymentIntents->selectOrderPaymentIntent((int)$order->id);
|
||||
|
||||
try {
|
||||
$stripePaymentIntents->delete();
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
}
|
||||
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'DELETE_PAYMENT_INTENT', 'Successfully deleted a payment intent (ID: ' . $id . ')');
|
||||
$response->success($this->buildStripePaymentIntentResponse(null, null, [
|
||||
'message' => 'Payment intent cleared successfully.',
|
||||
'cleared' => true,
|
||||
]));
|
||||
},
|
||||
[
|
||||
'charge_order' => 'Delete a payment intent'
|
||||
@@ -698,59 +719,76 @@ class ordersRoute
|
||||
);
|
||||
|
||||
$this->post('/orders/module/stripe/payment_intent/capture', function () {
|
||||
// Require the user to be logged in
|
||||
global $response;
|
||||
$this->requirePermission('confirm_payment_intent');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if ($user) {
|
||||
// Get the post data
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
// Check if the required fields are set
|
||||
if (!isset($data['id'])) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
// Get the current order
|
||||
$order = (new orders_o())->getOrderById((int)$data['id']);
|
||||
// Check if the order exists
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
// Check if the order has a payment intent
|
||||
$stripe_payment_intents = new stripe_payment_intents_o();
|
||||
if (!$stripe_payment_intents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$response->error('Order does not have a payment intent', 400);
|
||||
}
|
||||
$stripe_payment_intents->selectOrderPaymentIntent((int)$order->id);
|
||||
// Confirm the payment intent
|
||||
$stripe = new stripe();
|
||||
try {
|
||||
$paymentIntent = $stripe->payment_intents->capture(
|
||||
$stripe_payment_intents->payment_intent_id->value(),
|
||||
[] // Since we are capturing the payment, we don't need to pass any data
|
||||
);
|
||||
// Log the incident
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'CONFIRM_PAYMENT_INTENT', 'Successfully confirmed a payment intent (ID: ' . $data['id'] . ')');
|
||||
// Check if the payment intent was successful
|
||||
if ($paymentIntent->status !== 'succeeded') {
|
||||
$response->error('Payment intent not successful', 400);
|
||||
} else {
|
||||
// Update the order collection to reflect the payment
|
||||
$order_collection = $order->getOrderCollection();
|
||||
$order_collection->paidWithStripe($paymentIntent->id);
|
||||
}
|
||||
// Return a success message
|
||||
$response->success($paymentIntent->toJSON());
|
||||
} catch (\Stripe\Exception\InvalidRequestException $e) {
|
||||
$response->error('Payment intent not found', 400);
|
||||
}
|
||||
} else {
|
||||
// Log the incident
|
||||
if (!$user) {
|
||||
(new logs_o())->add('orders', 'global', 1, 0, 'CONFIRM_PAYMENT_INTENT', 'No user found, or invalid session');
|
||||
// Return an error
|
||||
$response->error('Invalid session', 400);
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
if (!isset($data['id'])) {
|
||||
$response->error('ID is required', 400);
|
||||
}
|
||||
|
||||
$order = (new orders_o())->getOrderById((int)$data['id']);
|
||||
if (!$order->exists()) {
|
||||
$response->error('Order not found', 400);
|
||||
}
|
||||
|
||||
$stripePaymentIntents = new stripe_payment_intents_o();
|
||||
if (!$stripePaymentIntents->doesOrderHavePaymentIntent((int)$order->id)) {
|
||||
$response->error('No active payment intent for this order.', 409);
|
||||
}
|
||||
|
||||
$stripePaymentIntents->selectOrderPaymentIntent((int)$order->id);
|
||||
$stripe = new stripe();
|
||||
|
||||
try {
|
||||
$paymentIntent = $stripe->payment_intents->get($stripePaymentIntents->payment_intent_id->value());
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
$response->error('Stored payment intent is stale. Start the payment again.', 409);
|
||||
}
|
||||
|
||||
$stripePaymentIntents->updateStoredPaymentIntent($paymentIntent);
|
||||
$status = strtolower((string)($paymentIntent->status ?? ''));
|
||||
|
||||
if ($status === 'succeeded') {
|
||||
$response->error('Payment intent has already been captured.', 409);
|
||||
}
|
||||
if ($status === 'canceled') {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
$response->error('Payment intent was cancelled. Start the payment again.', 409);
|
||||
}
|
||||
if ($status !== 'requires_capture') {
|
||||
$response->error('Payment intent is not ready to capture.', 409);
|
||||
}
|
||||
|
||||
try {
|
||||
$paymentIntent = $stripe->payment_intents->capture(
|
||||
$stripePaymentIntents->payment_intent_id->value(),
|
||||
[]
|
||||
);
|
||||
} catch (\Stripe\Exception\InvalidRequestException) {
|
||||
$stripePaymentIntents->deletePermanently();
|
||||
$response->error('Stored payment intent is stale. Start the payment again.', 409);
|
||||
}
|
||||
|
||||
$stripePaymentIntents->updateStoredPaymentIntent($paymentIntent);
|
||||
if (strtolower((string)($paymentIntent->status ?? '')) !== 'succeeded') {
|
||||
$response->error('Payment intent is not ready to capture.', 409);
|
||||
}
|
||||
|
||||
$order_collection = $order->getOrderCollection();
|
||||
$order_collection->paidWithStripe($paymentIntent->id);
|
||||
|
||||
(new logs_o())->add('orders', $order->department_id->value(), 1, $user->id, 'CONFIRM_PAYMENT_INTENT', 'Successfully confirmed a payment intent (ID: ' . $data['id'] . ')');
|
||||
$response->success($this->buildStripePaymentIntentResponse($paymentIntent, $stripePaymentIntents));
|
||||
},
|
||||
[
|
||||
'confirm_payment_intent' => 'Confirm a payment intent'
|
||||
@@ -802,6 +840,68 @@ class ordersRoute
|
||||
);
|
||||
}
|
||||
|
||||
private function addTaxNetAmount(float $net_amount, ?int $tax_percentage): float
|
||||
{
|
||||
if (empty($tax_percentage) || $tax_percentage <= 0) {
|
||||
return $net_amount;
|
||||
}
|
||||
|
||||
return $net_amount + ($net_amount * ($tax_percentage / 100));
|
||||
}
|
||||
|
||||
private function isStripePaymentIntentReusable(object $paymentIntent): bool
|
||||
{
|
||||
$status = strtolower((string)($paymentIntent->status ?? ''));
|
||||
|
||||
return in_array($status, [
|
||||
'requires_payment_method',
|
||||
'requires_confirmation',
|
||||
'requires_action',
|
||||
'processing',
|
||||
'requires_capture',
|
||||
'succeeded',
|
||||
], true);
|
||||
}
|
||||
|
||||
private function buildStripePaymentIntentResponse(?object $paymentIntent, ?stripe_payment_intents_o $storedIntent, array $extra = []): array
|
||||
{
|
||||
$paymentIntentPayload = null;
|
||||
if ($paymentIntent !== null) {
|
||||
if (method_exists($paymentIntent, 'toJSON')) {
|
||||
$decoded = json_decode($paymentIntent->toJSON(), true);
|
||||
$paymentIntentPayload = is_array($decoded) ? $decoded : null;
|
||||
} else {
|
||||
$decoded = json_decode(json_encode($paymentIntent), true);
|
||||
$paymentIntentPayload = is_array($decoded) ? $decoded : null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($paymentIntentPayload !== null) {
|
||||
$metadata = $paymentIntentPayload['metadata'] ?? [];
|
||||
if (!is_array($metadata)) {
|
||||
$metadata = [];
|
||||
}
|
||||
|
||||
if ($storedIntent !== null && isset($storedIntent->reader_id) && !empty($storedIntent->reader_id->value())) {
|
||||
$metadata['reader_id'] = (string)$storedIntent->reader_id->value();
|
||||
if (empty($metadata['reader'])) {
|
||||
$metadata['reader'] = $metadata['reader_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($storedIntent !== null && isset($storedIntent->tax_percentage) && $storedIntent->tax_percentage->value() !== null) {
|
||||
$metadata['tax_percentage'] = (string)$storedIntent->tax_percentage->value();
|
||||
}
|
||||
|
||||
$paymentIntentPayload['metadata'] = $metadata;
|
||||
}
|
||||
|
||||
return array_merge([
|
||||
'payment_intent' => $paymentIntentPayload,
|
||||
'has_payment_intent' => $paymentIntentPayload !== null,
|
||||
], $extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user