feat(order): wait for colleague callback before settling wallet

Keep cover orders pending until colleague sts 2/4/6 via callback or 35s poll. Nightly prices:prune also drops old log tables.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-02 15:55:03 +03:30
co-authored by Cursor
parent e9674d6571
commit 0b1e5c687b
13 changed files with 1093 additions and 105 deletions
+69 -3
View File
@@ -616,7 +616,7 @@ class MontzarService
? auth('customer')->user()->name
: ($data['customer']['name'] ?? '');
return [
$payload = [
'mazaneh' => (int) $mazaneh,
'amount' => (float) $data['amount'],
'description' => $this->config()->Config('name_fa') . ' - ' . $customerName,
@@ -625,6 +625,56 @@ class MontzarService
'cash' => $cash,
'input_mode' => 'gold',
];
if (
$this->config()->getBool('montzar_order_wait_callback', true)
&& isset($data['order'])
&& $data['order'] instanceof Order
) {
$payload['callback'] = app(ColleagueOrderCallbackService::class)->callbackUrl((int) $data['order']->id);
}
return $payload;
}
/**
* GET وضعیت سفارش روی نود همکار — مسیر از setting + شناسه سفارش همکار.
*
* @return array<string, mixed>|null
*/
public function fetchColleagueOrder(int $providerOrderId): ?array
{
if ($providerOrderId <= 0) {
return null;
}
$path = trim($this->config()->getString('montzar_order_status_path', '/server/customer/order'));
if ($path === '') {
$path = '/server/customer/order';
}
$url = $this->endpoint(rtrim($path, '/') . '/' . $providerOrderId);
$token = $this->getToken();
try {
$httpResponse = $this->http(15)->withToken($token)->get($url);
} catch (\Throwable $e) {
Log::warning('Montzar order status request failed', [
'url' => $url,
'error' => $e->getMessage(),
]);
return null;
}
$body = $this->decodeMontzarHttpBody($httpResponse);
if (is_array($body) && ($body['message'] ?? null) === 'no authorised') {
$token = $this->montzarLogin();
$httpResponse = $this->http(15)->withToken($token)->get($url);
$body = $this->decodeMontzarHttpBody($httpResponse);
}
return is_array($body) ? $body : null;
}
private function postToMontzar(string $url, string $token, array $payload)
@@ -755,7 +805,7 @@ class MontzarService
];
}
if (isset($item['sts']) && in_array((int) $item['sts'], [1, 2], true)) {
if (isset($item['sts']) && in_array((int) $item['sts'], [1, 2, 4], true)) {
return [
'ok' => true,
'provider_id' => !empty($item['id']) ? (int) $item['id'] : null,
@@ -764,6 +814,14 @@ class MontzarService
}
}
if (!empty($body['pending']) || !empty($body[0]['pending'])) {
return [
'ok' => true,
'provider_id' => $this->extractProviderOrderId($body),
'error' => null,
];
}
return [
'ok' => false,
'provider_id' => null,
@@ -777,16 +835,24 @@ class MontzarService
return (int) $body['id'];
}
if (!empty($body['order_id']) && is_numeric($body['order_id'])) {
return (int) $body['order_id'];
}
if (!empty($body['order']['id'])) {
return (int) $body['order']['id'];
}
foreach ([1, 2] as $index) {
foreach ([0, 1, 2] as $index) {
if (isset($body[$index]) && is_array($body[$index])) {
if (!empty($body[$index]['id'])) {
return (int) $body[$index]['id'];
}
if (!empty($body[$index]['order_id']) && is_numeric($body[$index]['order_id'])) {
return (int) $body[$index]['order_id'];
}
if (!empty($body[$index]['order']['id'])) {
return (int) $body[$index]['order']['id'];
}