Skip to content

Commit 733a560

Browse files
refactor: [Checkout] change payment and webhooks API contract (#4023)
1 parent 7513423 commit 733a560

File tree

2 files changed

+117
-36
lines changed

2 files changed

+117
-36
lines changed

crates/router/src/connector/checkout.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,30 +1242,43 @@ impl api::IncomingWebhook for Checkout {
12421242
.body
12431243
.parse_struct("CheckoutWebhookBody")
12441244
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
1245-
1246-
if checkout::is_chargeback_event(&details.transaction_type) {
1247-
return Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
1248-
api_models::payments::PaymentIdType::ConnectorTransactionId(
1249-
details
1250-
.data
1251-
.payment_id
1252-
.ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
1253-
),
1254-
));
1255-
}
1256-
if checkout::is_refund_event(&details.transaction_type) {
1257-
return Ok(api_models::webhooks::ObjectReferenceId::RefundId(
1258-
api_models::webhooks::RefundIdType::ConnectorRefundId(
1259-
details
1260-
.data
1261-
.action_id
1262-
.ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
1263-
),
1264-
));
1265-
}
1266-
Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
1267-
api_models::payments::PaymentIdType::ConnectorTransactionId(details.data.id),
1268-
))
1245+
let ref_id: api_models::webhooks::ObjectReferenceId =
1246+
if checkout::is_chargeback_event(&details.transaction_type) {
1247+
let reference = match details.data.reference {
1248+
Some(reference) => {
1249+
api_models::payments::PaymentIdType::PaymentAttemptId(reference)
1250+
}
1251+
None => api_models::payments::PaymentIdType::ConnectorTransactionId(
1252+
details
1253+
.data
1254+
.payment_id
1255+
.ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
1256+
),
1257+
};
1258+
api_models::webhooks::ObjectReferenceId::PaymentId(reference)
1259+
} else if checkout::is_refund_event(&details.transaction_type) {
1260+
let refund_reference = match details.data.reference {
1261+
Some(reference) => api_models::webhooks::RefundIdType::RefundId(reference),
1262+
None => api_models::webhooks::RefundIdType::ConnectorRefundId(
1263+
details
1264+
.data
1265+
.action_id
1266+
.ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
1267+
),
1268+
};
1269+
api_models::webhooks::ObjectReferenceId::RefundId(refund_reference)
1270+
} else {
1271+
let reference_id = match details.data.reference {
1272+
Some(reference) => {
1273+
api_models::payments::PaymentIdType::PaymentAttemptId(reference)
1274+
}
1275+
None => {
1276+
api_models::payments::PaymentIdType::ConnectorTransactionId(details.data.id)
1277+
}
1278+
};
1279+
api_models::webhooks::ObjectReferenceId::PaymentId(reference_id)
1280+
};
1281+
Ok(ref_id)
12691282
}
12701283

12711284
fn get_webhook_event_type(

crates/router/src/connector/checkout/transformers.rs

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ pub struct PaymentsRequest {
242242
pub return_url: ReturnUrl,
243243
pub capture: bool,
244244
pub reference: String,
245+
pub metadata: Option<Secret<serde_json::Value>>,
245246
}
246247

247248
#[derive(Debug, Serialize, Deserialize)]
@@ -428,6 +429,7 @@ impl TryFrom<&CheckoutRouterData<&types::PaymentsAuthorizeRouterData>> for Payme
428429
let connector_auth = &item.router_data.connector_auth_type;
429430
let auth_type: CheckoutAuthType = connector_auth.try_into()?;
430431
let processing_channel_id = auth_type.processing_channel_id;
432+
let metadata = item.router_data.request.metadata.clone();
431433
Ok(Self {
432434
source: source_var,
433435
amount: item.amount.to_owned(),
@@ -437,6 +439,7 @@ impl TryFrom<&CheckoutRouterData<&types::PaymentsAuthorizeRouterData>> for Payme
437439
return_url,
438440
capture,
439441
reference: item.router_data.connector_request_reference_id.clone(),
442+
metadata,
440443
})
441444
}
442445
}
@@ -450,6 +453,16 @@ pub enum CheckoutPaymentStatus {
450453
CardVerified,
451454
Declined,
452455
Captured,
456+
#[serde(rename = "Retry Scheduled")]
457+
RetryScheduled,
458+
Voided,
459+
#[serde(rename = "Partially Captured")]
460+
PartiallyCaptured,
461+
#[serde(rename = "Partially Refunded")]
462+
PartiallyRefunded,
463+
Refunded,
464+
Canceled,
465+
Expired,
453466
}
454467

455468
impl TryFrom<CheckoutWebhookEventType> for CheckoutPaymentStatus {
@@ -460,7 +473,14 @@ impl TryFrom<CheckoutWebhookEventType> for CheckoutPaymentStatus {
460473
CheckoutWebhookEventType::PaymentCaptured => Ok(Self::Captured),
461474
CheckoutWebhookEventType::PaymentDeclined => Ok(Self::Declined),
462475
CheckoutWebhookEventType::AuthenticationStarted
463-
| CheckoutWebhookEventType::AuthenticationApproved => Ok(Self::Pending),
476+
| CheckoutWebhookEventType::AuthenticationApproved
477+
| CheckoutWebhookEventType::AuthenticationAttempted => Ok(Self::Pending),
478+
CheckoutWebhookEventType::AuthenticationExpired
479+
| CheckoutWebhookEventType::AuthenticationFailed
480+
| CheckoutWebhookEventType::PaymentAuthenticationFailed
481+
| CheckoutWebhookEventType::PaymentCaptureDeclined => Ok(Self::Declined),
482+
CheckoutWebhookEventType::PaymentCanceled => Ok(Self::Canceled),
483+
CheckoutWebhookEventType::PaymentVoided => Ok(Self::Voided),
464484
CheckoutWebhookEventType::PaymentRefunded
465485
| CheckoutWebhookEventType::PaymentRefundDeclined
466486
| CheckoutWebhookEventType::DisputeReceived
@@ -494,10 +514,18 @@ impl ForeignFrom<(CheckoutPaymentStatus, Option<enums::CaptureMethod>)> for enum
494514
Self::Authorized
495515
}
496516
}
497-
CheckoutPaymentStatus::Captured => Self::Charged,
498-
CheckoutPaymentStatus::Declined => Self::Failure,
517+
CheckoutPaymentStatus::Captured
518+
| CheckoutPaymentStatus::PartiallyRefunded
519+
| CheckoutPaymentStatus::Refunded => Self::Charged,
520+
CheckoutPaymentStatus::PartiallyCaptured => Self::PartialCharged,
521+
CheckoutPaymentStatus::Declined
522+
| CheckoutPaymentStatus::Expired
523+
| CheckoutPaymentStatus::Canceled => Self::Failure,
499524
CheckoutPaymentStatus::Pending => Self::AuthenticationPending,
500-
CheckoutPaymentStatus::CardVerified => Self::Pending,
525+
CheckoutPaymentStatus::CardVerified | CheckoutPaymentStatus::RetryScheduled => {
526+
Self::Pending
527+
}
528+
CheckoutPaymentStatus::Voided => Self::Voided,
501529
}
502530
}
503531
}
@@ -514,10 +542,18 @@ impl ForeignFrom<(CheckoutPaymentStatus, CheckoutPaymentIntent)> for enums::Atte
514542
Self::Authorized
515543
}
516544
}
517-
CheckoutPaymentStatus::Captured => Self::Charged,
518-
CheckoutPaymentStatus::Declined => Self::Failure,
545+
CheckoutPaymentStatus::Captured
546+
| CheckoutPaymentStatus::PartiallyRefunded
547+
| CheckoutPaymentStatus::Refunded => Self::Charged,
548+
CheckoutPaymentStatus::PartiallyCaptured => Self::PartialCharged,
549+
CheckoutPaymentStatus::Declined
550+
| CheckoutPaymentStatus::Expired
551+
| CheckoutPaymentStatus::Canceled => Self::Failure,
519552
CheckoutPaymentStatus::Pending => Self::AuthenticationPending,
520-
CheckoutPaymentStatus::CardVerified => Self::Pending,
553+
CheckoutPaymentStatus::CardVerified | CheckoutPaymentStatus::RetryScheduled => {
554+
Self::Pending
555+
}
556+
CheckoutPaymentStatus::Voided => Self::Voided,
521557
}
522558
}
523559
}
@@ -537,10 +573,18 @@ impl ForeignFrom<(CheckoutPaymentStatus, Option<Balances>)> for enums::AttemptSt
537573
Self::Authorized
538574
}
539575
}
540-
CheckoutPaymentStatus::Captured => Self::Charged,
541-
CheckoutPaymentStatus::Declined => Self::Failure,
576+
CheckoutPaymentStatus::Captured
577+
| CheckoutPaymentStatus::PartiallyRefunded
578+
| CheckoutPaymentStatus::Refunded => Self::Charged,
579+
CheckoutPaymentStatus::PartiallyCaptured => Self::PartialCharged,
580+
CheckoutPaymentStatus::Declined
581+
| CheckoutPaymentStatus::Expired
582+
| CheckoutPaymentStatus::Canceled => Self::Failure,
542583
CheckoutPaymentStatus::Pending => Self::AuthenticationPending,
543-
CheckoutPaymentStatus::CardVerified => Self::Pending,
584+
CheckoutPaymentStatus::CardVerified | CheckoutPaymentStatus::RetryScheduled => {
585+
Self::Pending
586+
}
587+
CheckoutPaymentStatus::Voided => Self::Voided,
544588
}
545589
}
546590
}
@@ -559,6 +603,7 @@ pub struct Links {
559603
pub struct PaymentsResponse {
560604
id: String,
561605
amount: Option<i32>,
606+
currency: Option<String>,
562607
action_id: Option<String>,
563608
status: CheckoutPaymentStatus,
564609
#[serde(rename = "_links")]
@@ -567,6 +612,8 @@ pub struct PaymentsResponse {
567612
reference: Option<String>,
568613
response_code: Option<String>,
569614
response_summary: Option<String>,
615+
approved: Option<bool>,
616+
processed_on: Option<String>,
570617
}
571618

572619
#[derive(Debug, Deserialize, Serialize)]
@@ -1132,11 +1179,18 @@ pub fn is_chargeback_event(event_code: &CheckoutWebhookEventType) -> bool {
11321179
pub enum CheckoutWebhookEventType {
11331180
AuthenticationStarted,
11341181
AuthenticationApproved,
1182+
AuthenticationAttempted,
1183+
AuthenticationExpired,
1184+
AuthenticationFailed,
11351185
PaymentApproved,
11361186
PaymentCaptured,
11371187
PaymentDeclined,
11381188
PaymentRefunded,
11391189
PaymentRefundDeclined,
1190+
PaymentAuthenticationFailed,
1191+
PaymentCanceled,
1192+
PaymentCaptureDeclined,
1193+
PaymentVoided,
11401194
DisputeReceived,
11411195
DisputeExpired,
11421196
DisputeAccepted,
@@ -1169,6 +1223,8 @@ pub struct CheckoutWebhookData {
11691223
pub response_code: Option<String>,
11701224
pub response_summary: Option<String>,
11711225
pub currency: String,
1226+
pub processed_on: Option<String>,
1227+
pub approved: Option<bool>,
11721228
}
11731229

11741230
#[derive(Debug, Deserialize)]
@@ -1220,13 +1276,22 @@ pub enum CheckoutDisputeTransactionType {
12201276
impl From<CheckoutWebhookEventType> for api::IncomingWebhookEvent {
12211277
fn from(transaction_type: CheckoutWebhookEventType) -> Self {
12221278
match transaction_type {
1223-
CheckoutWebhookEventType::AuthenticationStarted => Self::EventNotSupported,
1224-
CheckoutWebhookEventType::AuthenticationApproved => Self::EventNotSupported,
1279+
CheckoutWebhookEventType::AuthenticationStarted
1280+
| CheckoutWebhookEventType::AuthenticationApproved
1281+
| CheckoutWebhookEventType::AuthenticationAttempted => Self::EventNotSupported,
1282+
CheckoutWebhookEventType::AuthenticationExpired
1283+
| CheckoutWebhookEventType::AuthenticationFailed
1284+
| CheckoutWebhookEventType::PaymentAuthenticationFailed => {
1285+
Self::PaymentIntentAuthorizationFailure
1286+
}
12251287
CheckoutWebhookEventType::PaymentApproved => Self::EventNotSupported,
12261288
CheckoutWebhookEventType::PaymentCaptured => Self::PaymentIntentSuccess,
12271289
CheckoutWebhookEventType::PaymentDeclined => Self::PaymentIntentFailure,
12281290
CheckoutWebhookEventType::PaymentRefunded => Self::RefundSuccess,
12291291
CheckoutWebhookEventType::PaymentRefundDeclined => Self::RefundFailure,
1292+
CheckoutWebhookEventType::PaymentCanceled => Self::PaymentIntentCancelFailure,
1293+
CheckoutWebhookEventType::PaymentCaptureDeclined => Self::PaymentIntentCaptureFailure,
1294+
CheckoutWebhookEventType::PaymentVoided => Self::PaymentIntentCancelled,
12301295
CheckoutWebhookEventType::DisputeReceived
12311296
| CheckoutWebhookEventType::DisputeEvidenceRequired => Self::DisputeOpened,
12321297
CheckoutWebhookEventType::DisputeExpired => Self::DisputeExpired,
@@ -1329,6 +1394,9 @@ impl TryFrom<&api::IncomingWebhookRequestDetails<'_>> for PaymentsResponse {
13291394
response_code: data.response_code,
13301395
response_summary: data.response_summary,
13311396
action_id: data.action_id,
1397+
currency: Some(data.currency),
1398+
processed_on: data.processed_on,
1399+
approved: data.approved,
13321400
};
13331401

13341402
Ok(psync_struct)

0 commit comments

Comments
 (0)