Fix ABDM HIU auto-flow duplicate consent handling

This commit is contained in:
DevSoftTech Server 2026-07-27 14:12:56 +05:30
parent 9730f9a450
commit 92a954a4cd
2 changed files with 106 additions and 19 deletions

View File

@ -1375,18 +1375,36 @@ class Patient extends BaseController
}
if ((int) ($consentResult['ok'] ?? 0) !== 1) {
$httpCode = (int) ($consentResult['http_code'] ?? 422);
if ($httpCode < 100 || $httpCode > 599) {
$httpCode = 422;
$errorText = trim((string) ($consentResult['error_text'] ?? 'Consent request failed.'));
$isDuplicateConsent = stripos($errorText, 'ABDM-1070') !== false
|| stripos($errorText, 'Duplicate consent request') !== false;
if ($isDuplicateConsent) {
$existingRequestId = $this->findLatestAbdmGatewayRequestId($abhaContext['abha_address']);
if ($existingRequestId !== '') {
$consentResult['ok'] = 1;
$consentResult['http_code'] = 200;
$consentResult['request_id'] = $existingRequestId;
$consentResult['workflow_state'] = 'REQUESTED';
$consentResult['reused_existing_request'] = 1;
$consentResult['message'] = 'Duplicate consent detected. Reusing latest request for reconciliation.';
}
}
return $this->response->setStatusCode($httpCode)->setJSON([
'ok' => 0,
'phase' => 'REQUEST_FAILED',
'error' => (string) ($consentResult['error_text'] ?? 'Consent request failed.'),
'request_id' => (string) ($consentResult['request_id'] ?? ''),
'data' => $consentResult,
]);
if ((int) ($consentResult['ok'] ?? 0) !== 1) {
$httpCode = (int) ($consentResult['http_code'] ?? 422);
if ($httpCode < 100 || $httpCode > 599) {
$httpCode = 422;
}
return $this->response->setStatusCode($httpCode)->setJSON([
'ok' => 0,
'phase' => 'REQUEST_FAILED',
'error' => (string) ($consentResult['error_text'] ?? 'Consent request failed.'),
'request_id' => (string) ($consentResult['request_id'] ?? ''),
'data' => $consentResult,
]);
}
}
$flowRefId = trim((string) (
@ -1401,9 +1419,6 @@ class Patient extends BaseController
?? $consentResult['abdm_consent_request_id']
?? ''
));
if ($consentRequestRef === '') {
$consentRequestRef = $flowRefId;
}
$consentArtifactRef = trim((string) (
$consentResult['consent_id']
?? $consentResult['abdm_consent_artifact_id']
@ -1422,13 +1437,21 @@ class Patient extends BaseController
]);
}
if ($consentRequestRef === '' && preg_match('/^REQ-HIU-/i', $flowRefId) === 1) {
$resolvedRequestId = $this->findLatestAbdmGatewayRequestId($abhaContext['abha_address']);
if ($resolvedRequestId !== '') {
$flowRefId = $resolvedRequestId;
}
}
$reconcilePayload = [
'abha_address' => $abhaContext['abha_address'],
];
if ($flowRefId !== '') {
$reconcilePayload['request_id'] = $flowRefId;
}
if ($consentRequestRef !== '') {
$reconcilePayload['consentRequestId'] = $consentRequestRef;
} else {
$reconcilePayload['request_id'] = $flowRefId;
}
try {
@ -2729,5 +2752,53 @@ class Patient extends BaseController
return 'REQUESTED';
}
private function findLatestAbdmGatewayRequestId(string $abhaAddress): string
{
$abhaAddress = trim($abhaAddress);
if ($abhaAddress === '' || ! $this->db->tableExists('abdm_hiu_workflows')) {
return '';
}
$fields = $this->db->getFieldNames('abdm_hiu_workflows') ?? [];
$select = ['request_id', 'response_json'];
if (in_array('gateway_request_id', $fields, true)) {
$select[] = 'gateway_request_id';
}
if (in_array('hms_request_id', $fields, true)) {
$select[] = 'hms_request_id';
}
$rows = $this->db->table('abdm_hiu_workflows')
->select(implode(', ', $select))
->where('operation', 'consent_request')
->where('abha_address', $abhaAddress)
->where('status', 'success')
->orderBy('id', 'DESC')
->get(20)
->getResultArray();
foreach ($rows as $row) {
$candidates = [
trim((string) ($row['gateway_request_id'] ?? '')),
trim((string) ($row['request_id'] ?? '')),
];
$decoded = json_decode((string) ($row['response_json'] ?? ''), true);
if (is_array($decoded)) {
$candidates[] = trim((string) ($decoded['gateway_request_id'] ?? ''));
$candidates[] = trim((string) ($decoded['request_id'] ?? ''));
$candidates[] = trim((string) ($decoded['requestId'] ?? ''));
}
foreach ($candidates as $candidate) {
if ($candidate !== '' && preg_match('/^REQ-/i', $candidate) === 1) {
return $candidate;
}
}
}
return '';
}
}

View File

@ -602,6 +602,7 @@ class M3HiuWorkflowService
private function normalizePayload(array $payload): array
{
$normalized = $payload;
$generatedRequestId = false;
// Accept both legacy snake_case and guide-defined camelCase keys.
if (! isset($normalized['request_id']) && isset($normalized['requestId'])) {
@ -641,6 +642,7 @@ class M3HiuWorkflowService
if ($normalized['request_id'] === '') {
$normalized['request_id'] = 'REQ-HIU-' . date('YmdHis') . '-' . strtoupper(bin2hex(random_bytes(3)));
$generatedRequestId = true;
}
if (! isset($normalized['requestId']) || trim((string) $normalized['requestId']) === '') {
@ -656,11 +658,14 @@ class M3HiuWorkflowService
$normalized['consentId'] = $normalized['consent_id'];
}
$normalized['__generated_request_id'] = $generatedRequestId ? 1 : 0;
return $normalized;
}
private function preparePayloadForOperation(string $operation, array $normalized): array
{
$requestIdGenerated = (int) ($normalized['__generated_request_id'] ?? 0) === 1;
$clean = $this->stripInternalNoise($normalized);
$requestId = trim((string) ($clean['requestId'] ?? $clean['request_id'] ?? ''));
if ($requestId === '') {
@ -794,6 +799,9 @@ class M3HiuWorkflowService
if ($operation === 'consent_reconcile') {
$requestIdRef = trim((string) ($clean['request_id'] ?? $clean['requestId'] ?? ''));
if ($requestIdGenerated) {
$requestIdRef = '';
}
$consentRequestId = trim((string) ($clean['abdm_consent_request_id'] ?? $clean['consentRequestId'] ?? ''));
$consentId = trim((string) ($clean['abdm_consent_artifact_id'] ?? $clean['consentId'] ?? $clean['consent_id'] ?? ''));
@ -823,6 +831,15 @@ class M3HiuWorkflowService
}
if ($operation === 'data_fetch') {
$requestFallback = '';
if (! $requestIdGenerated) {
$requestFallback = trim((string) (
$clean['request_id']
?? $clean['requestId']
?? ''
));
}
$consentId = trim((string) (
$clean['abdm_consent_artifact_id']
?? $clean['consentId']
@ -830,9 +847,7 @@ class M3HiuWorkflowService
?? $clean['abdm_consent_request_id']
?? $clean['consentRequestId']
?? $clean['consent_request_id']
?? $clean['request_id']
?? $clean['requestId']
?? ''
?? $requestFallback
));
if ($consentId === '') {
$consentId = $this->resolveAbdmConsentArtifactIdFromWorkflow($clean);
@ -871,7 +886,8 @@ class M3HiuWorkflowService
$payload['csrf_test_name'],
$payload['patient_id'],
$payload['abha_id'],
$payload['abhaId']
$payload['abhaId'],
$payload['__generated_request_id']
);
if (isset($payload['requestId'])) {