fix: harden pakasir qris parsing and remove legacy compose envs

This commit is contained in:
Dwindi Ramadhana
2026-02-15 00:18:16 +07:00
parent 3d41cea158
commit 2795e0b927
2 changed files with 61 additions and 15 deletions

View File

@@ -77,7 +77,11 @@ class PakasirController extends Controller
];
$endpoint = $apiBase.'/api/transactioncreate/qris';
$res = Http::asForm()->timeout($timeout)->post($endpoint, $payload);
$res = Http::timeout($timeout)->post($endpoint, $payload);
if (!$res->successful()) {
// Fallback for gateways expecting x-www-form-urlencoded payloads.
$res = Http::asForm()->timeout($timeout)->post($endpoint, $payload);
}
if (!$res->successful()) {
Log::warning('Pakasir create transaction failed', [
@@ -89,11 +93,22 @@ class PakasirController extends Controller
}
$body = $res->json();
$payment = is_array($body['payment'] ?? null) ? $body['payment'] : $body;
$paymentNumber = (string) ($payment['payment_number'] ?? '');
$status = (string) ($payment['status'] ?? 'pending');
$expiredAt = (string) ($payment['expired_at'] ?? '');
$totalPayment = (int) ($payment['total_payment'] ?? $amountIdr);
if (!is_array($body)) {
Log::warning('Pakasir create transaction invalid response', [
'endpoint' => $endpoint,
'body' => $res->body(),
]);
return response()->json(['error' => 'pakasir_invalid_response'], 502);
}
[$paymentNumber, $status, $expiredAt, $totalPayment] = $this->extractPakasirPayload($body, $amountIdr);
if ($paymentNumber === '') {
Log::warning('Pakasir create transaction missing QR value', [
'endpoint' => $endpoint,
'body' => $body,
]);
return response()->json(['error' => 'pakasir_invalid_response'], 502);
}
$order->update([
'provider_ref' => $orderRef,
@@ -124,6 +139,46 @@ class PakasirController extends Controller
]);
}
/**
* @param array<string,mixed> $body
* @return array{0:string,1:string,2:string,3:int}
*/
private function extractPakasirPayload(array $body, int $amountFallback): array
{
$payment = $body;
if (is_array($body['payment'] ?? null)) {
$payment = $body['payment'];
} elseif (is_array($body['data'] ?? null)) {
$payment = $body['data'];
}
$paymentNumber = (string) (
$payment['payment_number']
?? $payment['qris_string']
?? $payment['qr_string']
?? $payment['qr_value']
?? ''
);
$status = (string) ($payment['status'] ?? $body['status'] ?? 'pending');
$expiredAt = (string) (
$payment['expired_at']
?? $payment['expires_at']
?? $payment['expired']
?? ''
);
$totalPayment = (int) (
$payment['total_payment']
?? $payment['amount']
?? $body['total_payment']
?? $body['amount']
?? $amountFallback
);
return [$paymentNumber, $status, $expiredAt, $totalPayment];
}
public function cancelPending(Request $request): JsonResponse
{
$user = $request->user();

View File

@@ -28,15 +28,6 @@ services:
QUEUE_CONNECTION: ${QUEUE_CONNECTION:-sync}
DEWEMOJI_BILLING_MODE: ${DEWEMOJI_BILLING_MODE:-sandbox}
DEWEMOJI_GUMROAD_ENABLED: ${DEWEMOJI_GUMROAD_ENABLED:-false}
DEWEMOJI_GUMROAD_PRODUCT_IDS: ${DEWEMOJI_GUMROAD_PRODUCT_IDS:-}
DEWEMOJI_GUMROAD_TEST_KEYS: ${DEWEMOJI_GUMROAD_TEST_KEYS:-}
DEWEMOJI_MAYAR_ENABLED: ${DEWEMOJI_MAYAR_ENABLED:-false}
DEWEMOJI_MAYAR_API_BASE: ${DEWEMOJI_MAYAR_API_BASE:-}
DEWEMOJI_MAYAR_ENDPOINT_VERIFY: ${DEWEMOJI_MAYAR_ENDPOINT_VERIFY:-/v1/license/verify}
DEWEMOJI_MAYAR_PRODUCT_IDS: ${DEWEMOJI_MAYAR_PRODUCT_IDS:-}
DEWEMOJI_MAYAR_API_KEY: ${DEWEMOJI_MAYAR_API_KEY:-}
DEWEMOJI_MAYAR_SECRET_KEY: ${DEWEMOJI_MAYAR_SECRET_KEY:-}
WAIT_FOR_DB: ${WAIT_FOR_DB:-true}
RUN_MIGRATIONS: ${RUN_MIGRATIONS:-true}