Skip to content

Commit 500405d

Browse files
authored
feat(connector): [Paypal] use connector request reference id as reference for paypal (#2577)
1 parent b5feab6 commit 500405d

File tree

2 files changed

+66
-21
lines changed

2 files changed

+66
-21
lines changed

crates/router/src/connector/paypal.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ impl api::IncomingWebhook for Paypal {
10911091
resource
10921092
.purchase_units
10931093
.first()
1094-
.map(|unit| unit.reference_id.clone())
1094+
.and_then(|unit| unit.invoice_id.clone().or(unit.reference_id.clone()))
10951095
.ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
10961096
),
10971097
))

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

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ pub struct OrderAmount {
7373

7474
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
7575
pub struct PurchaseUnitRequest {
76-
reference_id: String,
76+
reference_id: Option<String>, //reference for an item in purchase_units
77+
invoice_id: Option<String>, //The API caller-provided external invoice number for this order. Appears in both the payer's transaction history and the emails that the payer receives.
78+
custom_id: Option<String>, //Used to reconcile client transactions with PayPal transactions.
7779
amount: OrderAmount,
7880
}
7981

@@ -260,10 +262,13 @@ impl TryFrom<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for PaypalP
260262
currency_code: item.router_data.request.currency,
261263
value: item.amount.to_owned(),
262264
};
263-
let reference_id = item.router_data.attempt_id.clone();
265+
let connector_request_reference_id =
266+
item.router_data.connector_request_reference_id.clone();
264267

265268
let purchase_units = vec![PurchaseUnitRequest {
266-
reference_id,
269+
reference_id: Some(connector_request_reference_id.clone()),
270+
custom_id: Some(connector_request_reference_id.clone()),
271+
invoice_id: Some(connector_request_reference_id),
267272
amount,
268273
}];
269274
let card = item.router_data.request.get_card()?;
@@ -304,9 +309,14 @@ impl TryFrom<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for PaypalP
304309
currency_code: item.router_data.request.currency,
305310
value: item.amount.to_owned(),
306311
};
307-
let reference_id = item.router_data.attempt_id.clone();
312+
313+
let connector_req_reference_id =
314+
item.router_data.connector_request_reference_id.clone();
315+
308316
let purchase_units = vec![PurchaseUnitRequest {
309-
reference_id,
317+
reference_id: Some(connector_req_reference_id.clone()),
318+
custom_id: Some(connector_req_reference_id.clone()),
319+
invoice_id: Some(connector_req_reference_id),
310320
amount,
311321
}];
312322
let payment_source =
@@ -367,9 +377,13 @@ impl TryFrom<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for PaypalP
367377
currency_code: item.router_data.request.currency,
368378
value: item.amount.to_owned(),
369379
};
370-
let reference_id = item.router_data.attempt_id.clone();
380+
let connector_req_reference_id =
381+
item.router_data.connector_request_reference_id.clone();
382+
371383
let purchase_units = vec![PurchaseUnitRequest {
372-
reference_id,
384+
reference_id: Some(connector_req_reference_id.clone()),
385+
custom_id: Some(connector_req_reference_id.clone()),
386+
invoice_id: Some(connector_req_reference_id),
373387
amount,
374388
}];
375389
let payment_source =
@@ -655,7 +669,8 @@ pub struct PaymentsCollection {
655669

656670
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
657671
pub struct PurchaseUnitItem {
658-
pub reference_id: String,
672+
pub reference_id: Option<String>,
673+
pub invoice_id: Option<String>,
659674
pub payments: PaymentsCollection,
660675
}
661676

@@ -680,11 +695,17 @@ pub struct PaypalLinks {
680695
rel: String,
681696
}
682697

698+
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
699+
pub struct RedirectPurchaseUnitItem {
700+
pub invoice_id: String,
701+
}
702+
683703
#[derive(Debug, Clone, Serialize, Deserialize)]
684704
pub struct PaypalRedirectResponse {
685705
id: String,
686706
intent: PaypalPaymentIntent,
687707
status: PaypalOrderStatus,
708+
purchase_units: Vec<RedirectPurchaseUnitItem>,
688709
links: Vec<PaypalLinks>,
689710
}
690711

@@ -712,6 +733,7 @@ pub struct PaypalPaymentsSyncResponse {
712733
id: String,
713734
status: PaypalPaymentStatus,
714735
amount: OrderAmount,
736+
invoice_id: Option<String>,
715737
supplementary_data: PaypalSupplementaryData,
716738
}
717739

@@ -792,7 +814,7 @@ impl<F, T>
792814
capture_id: Some(id),
793815
psync_flow: item.response.intent.clone()
794816
}),
795-
types::ResponseId::ConnectorTransactionId(item.response.id),
817+
types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
796818
),
797819

798820
PaypalPaymentIntent::Authorize => (
@@ -801,7 +823,7 @@ impl<F, T>
801823
capture_id: None,
802824
psync_flow: item.response.intent.clone()
803825
}),
804-
types::ResponseId::ConnectorTransactionId(item.response.id),
826+
types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
805827
),
806828

807829
PaypalPaymentIntent::Authenticate => {
@@ -836,7 +858,10 @@ impl<F, T>
836858
mandate_reference: None,
837859
connector_metadata: Some(connector_meta),
838860
network_txn_id: None,
839-
connector_response_reference_id: None,
861+
connector_response_reference_id: purchase_units
862+
.invoice_id
863+
.clone()
864+
.or(Some(item.response.id)),
840865
}),
841866
..item.data
842867
})
@@ -925,19 +950,22 @@ impl<F, T>
925950
capture_id: None,
926951
psync_flow: item.response.intent
927952
});
953+
let purchase_units = item.response.purchase_units.first();
928954

929955
Ok(Self {
930956
status,
931957
response: Ok(types::PaymentsResponseData::TransactionResponse {
932-
resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
958+
resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
933959
redirection_data: Some(services::RedirectForm::from((
934960
link.ok_or(errors::ConnectorError::ResponseDeserializationFailed)?,
935961
services::Method::Get,
936962
))),
937963
mandate_reference: None,
938964
connector_metadata: Some(connector_meta),
939965
network_txn_id: None,
940-
connector_response_reference_id: None,
966+
connector_response_reference_id: Some(
967+
purchase_units.map_or(item.response.id, |item| item.invoice_id.clone()),
968+
),
941969
}),
942970
..item.data
943971
})
@@ -1075,13 +1103,21 @@ impl<F, T>
10751103
status: storage_enums::AttemptStatus::from(item.response.status),
10761104
response: Ok(types::PaymentsResponseData::TransactionResponse {
10771105
resource_id: types::ResponseId::ConnectorTransactionId(
1078-
item.response.supplementary_data.related_ids.order_id,
1106+
item.response
1107+
.supplementary_data
1108+
.related_ids
1109+
.order_id
1110+
.clone(),
10791111
),
10801112
redirection_data: None,
10811113
mandate_reference: None,
10821114
connector_metadata: None,
10831115
network_txn_id: None,
1084-
connector_response_reference_id: None,
1116+
connector_response_reference_id: item
1117+
.response
1118+
.invoice_id
1119+
.clone()
1120+
.or(Some(item.response.supplementary_data.related_ids.order_id)),
10851121
}),
10861122
..item.data
10871123
})
@@ -1133,6 +1169,7 @@ pub struct PaypalCaptureResponse {
11331169
id: String,
11341170
status: PaypalPaymentStatus,
11351171
amount: Option<OrderAmount>,
1172+
invoice_id: Option<String>,
11361173
final_capture: bool,
11371174
}
11381175

@@ -1174,11 +1211,14 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<PaypalCaptureResponse>>
11741211
mandate_reference: None,
11751212
connector_metadata: Some(serde_json::json!(PaypalMeta {
11761213
authorize_id: connector_payment_id.authorize_id,
1177-
capture_id: Some(item.response.id),
1214+
capture_id: Some(item.response.id.clone()),
11781215
psync_flow: PaypalPaymentIntent::Capture
11791216
})),
11801217
network_txn_id: None,
1181-
connector_response_reference_id: None,
1218+
connector_response_reference_id: item
1219+
.response
1220+
.invoice_id
1221+
.or(Some(item.response.id)),
11821222
}),
11831223
amount_captured: Some(amount_captured),
11841224
..item.data
@@ -1193,11 +1233,11 @@ pub enum PaypalCancelStatus {
11931233
}
11941234

11951235
#[derive(Debug, Serialize, Deserialize, PartialEq)]
1196-
#[serde(rename_all = "camelCase")]
11971236
pub struct PaypalPaymentsCancelResponse {
11981237
id: String,
11991238
status: PaypalCancelStatus,
12001239
amount: Option<OrderAmount>,
1240+
invoice_id: Option<String>,
12011241
}
12021242

12031243
impl<F, T>
@@ -1220,12 +1260,15 @@ impl<F, T>
12201260
Ok(Self {
12211261
status,
12221262
response: Ok(types::PaymentsResponseData::TransactionResponse {
1223-
resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
1263+
resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
12241264
redirection_data: None,
12251265
mandate_reference: None,
12261266
connector_metadata: None,
12271267
network_txn_id: None,
1228-
connector_response_reference_id: None,
1268+
connector_response_reference_id: item
1269+
.response
1270+
.invoice_id
1271+
.or(Some(item.response.id)),
12291272
}),
12301273
..item.data
12311274
})
@@ -1408,6 +1451,7 @@ pub struct PaypalSellerPayableBreakdown {
14081451
pub struct PaypalCardWebhooks {
14091452
pub supplementary_data: PaypalSupplementaryData,
14101453
pub amount: OrderAmount,
1454+
pub invoice_id: Option<String>,
14111455
}
14121456

14131457
#[derive(Deserialize, Debug, Serialize)]
@@ -1528,6 +1572,7 @@ impl TryFrom<(PaypalCardWebhooks, PaypalWebhookEventType)> for PaypalPaymentsSyn
15281572
status: PaypalPaymentStatus::try_from(webhook_event)?,
15291573
amount: webhook_body.amount,
15301574
supplementary_data: webhook_body.supplementary_data,
1575+
invoice_id: webhook_body.invoice_id,
15311576
})
15321577
}
15331578
}

0 commit comments

Comments
 (0)