@@ -19,7 +19,7 @@ use hyperswitch_domain_models::{
19
19
} ,
20
20
router_data:: {
21
21
AdditionalPaymentMethodConnectorResponse , ConnectorAuthType , ConnectorResponseData ,
22
- ErrorResponse , RouterData ,
22
+ ErrorResponse , L2L3Data , RouterData ,
23
23
} ,
24
24
router_flow_types:: {
25
25
refunds:: { Execute , RSync } ,
@@ -94,9 +94,6 @@ trait NuveiAuthorizePreprocessingCommon {
94
94
& self ,
95
95
) -> Result < PaymentMethodData , error_stack:: Report < errors:: ConnectorError > > ;
96
96
fn get_is_partial_approval ( & self ) -> Option < PartialApprovalFlag > ;
97
- fn get_order_tax_amount (
98
- & self ,
99
- ) -> Result < Option < MinorUnit > , error_stack:: Report < errors:: ConnectorError > > ;
100
97
fn is_customer_initiated_mandate_payment ( & self ) -> bool ;
101
98
}
102
99
@@ -158,11 +155,6 @@ impl NuveiAuthorizePreprocessingCommon for SetupMandateRequestData {
158
155
) -> Result < PaymentMethodData , error_stack:: Report < errors:: ConnectorError > > {
159
156
Ok ( self . payment_method_data . clone ( ) )
160
157
}
161
- fn get_order_tax_amount (
162
- & self ,
163
- ) -> Result < Option < MinorUnit > , error_stack:: Report < errors:: ConnectorError > > {
164
- Ok ( None )
165
- }
166
158
167
159
fn get_minor_amount_required (
168
160
& self ,
@@ -243,11 +235,6 @@ impl NuveiAuthorizePreprocessingCommon for PaymentsAuthorizeData {
243
235
) -> Result < PaymentMethodData , error_stack:: Report < errors:: ConnectorError > > {
244
236
Ok ( self . payment_method_data . clone ( ) )
245
237
}
246
- fn get_order_tax_amount (
247
- & self ,
248
- ) -> Result < Option < MinorUnit > , error_stack:: Report < errors:: ConnectorError > > {
249
- Ok ( self . order_tax_amount )
250
- }
251
238
252
239
fn get_email_required ( & self ) -> Result < Email , error_stack:: Report < errors:: ConnectorError > > {
253
240
self . get_email ( )
@@ -325,11 +312,6 @@ impl NuveiAuthorizePreprocessingCommon for PaymentsPreProcessingData {
325
312
. into ( ) ,
326
313
)
327
314
}
328
- fn get_order_tax_amount (
329
- & self ,
330
- ) -> Result < Option < MinorUnit > , error_stack:: Report < errors:: ConnectorError > > {
331
- Ok ( None )
332
- }
333
315
334
316
fn get_is_partial_approval ( & self ) -> Option < PartialApprovalFlag > {
335
317
None
@@ -376,8 +358,62 @@ pub struct NuveiSessionResponse {
376
358
377
359
#[ derive( Debug , Serialize , Default ) ]
378
360
#[ serde( rename_all = "camelCase" ) ]
379
- pub struct NuvieAmountDetails {
380
- total_tax : Option < StringMajorUnit > ,
361
+ pub struct NuveiAmountDetails {
362
+ pub total_tax : Option < StringMajorUnit > ,
363
+ pub total_shipping : Option < StringMajorUnit > ,
364
+ pub total_handling : Option < StringMajorUnit > ,
365
+ pub total_discount : Option < StringMajorUnit > ,
366
+ }
367
+
368
+ #[ derive( Debug , Serialize , Deserialize , Clone , Default ) ]
369
+ #[ serde( rename_all = "snake_case" ) ]
370
+ pub enum NuveiItemType {
371
+ #[ default]
372
+ Physical ,
373
+ Discount ,
374
+ #[ serde( rename = "Shipping_fee" ) ]
375
+ ShippingFee ,
376
+ Digital ,
377
+ #[ serde( rename = "Gift_card" ) ]
378
+ GiftCard ,
379
+ #[ serde( rename = "Store_credit" ) ]
380
+ StoreCredit ,
381
+ Surcharge ,
382
+ #[ serde( rename = "Sales_tax" ) ]
383
+ SalesTax ,
384
+ }
385
+ impl From < Option < enums:: ProductType > > for NuveiItemType {
386
+ fn from ( value : Option < enums:: ProductType > ) -> Self {
387
+ match value {
388
+ Some ( enums:: ProductType :: Digital ) => Self :: Digital ,
389
+ Some ( enums:: ProductType :: Physical ) => Self :: Physical ,
390
+ Some ( enums:: ProductType :: Ride )
391
+ | Some ( enums:: ProductType :: Travel )
392
+ | Some ( enums:: ProductType :: Accommodation ) => Self :: ShippingFee ,
393
+ _ => Self :: Physical ,
394
+ }
395
+ }
396
+ }
397
+
398
+ #[ serde_with:: skip_serializing_none]
399
+ #[ derive( Debug , Serialize , Default ) ]
400
+ #[ serde( rename_all = "camelCase" ) ]
401
+ pub struct NuveiItem {
402
+ pub name : String ,
403
+ #[ serde( rename = "type" ) ]
404
+ pub item_type : NuveiItemType ,
405
+ pub price : StringMajorUnit ,
406
+ pub quantity : String ,
407
+ pub group_id : Option < String > ,
408
+ pub discount : Option < StringMajorUnit > ,
409
+ pub discount_rate : Option < String > ,
410
+ pub shipping : Option < StringMajorUnit > ,
411
+ pub shipping_tax : Option < StringMajorUnit > ,
412
+ pub shipping_tax_rate : Option < String > ,
413
+ pub tax : Option < StringMajorUnit > ,
414
+ pub tax_rate : Option < String > ,
415
+ pub image_url : Option < String > ,
416
+ pub product_url : Option < String > ,
381
417
}
382
418
#[ serde_with:: skip_serializing_none]
383
419
#[ derive( Debug , Serialize , Default ) ]
@@ -404,7 +440,8 @@ pub struct NuveiPaymentsRequest {
404
440
pub shipping_address : Option < ShippingAddress > ,
405
441
pub related_transaction_id : Option < String > ,
406
442
pub url_details : Option < UrlDetails > ,
407
- pub amount_details : Option < NuvieAmountDetails > ,
443
+ pub amount_details : Option < NuveiAmountDetails > ,
444
+ pub items : Option < Vec < NuveiItem > > ,
408
445
pub is_partial_approval : Option < PartialApprovalFlag > ,
409
446
pub external_scheme_details : Option < ExternalSchemeDetails > ,
410
447
}
@@ -1424,6 +1461,94 @@ where
1424
1461
..Default :: default ( )
1425
1462
} )
1426
1463
}
1464
+ fn get_l2_l3_items (
1465
+ l2_l3_data : & Option < L2L3Data > ,
1466
+ currency : enums:: Currency ,
1467
+ ) -> Result < Option < Vec < NuveiItem > > , error_stack:: Report < errors:: ConnectorError > > {
1468
+ l2_l3_data. as_ref ( ) . map_or ( Ok ( None ) , |data| {
1469
+ data. order_details
1470
+ . as_ref ( )
1471
+ . map_or ( Ok ( None ) , |order_details_list| {
1472
+ // Map each order to a Result<NuveiItem>
1473
+ let results: Vec < Result < NuveiItem , error_stack:: Report < errors:: ConnectorError > > > =
1474
+ order_details_list
1475
+ . iter ( )
1476
+ . map ( |order| {
1477
+ let discount = order
1478
+ . unit_discount_amount
1479
+ . map ( |amount| {
1480
+ convert_amount ( NUVEI_AMOUNT_CONVERTOR , amount, currency)
1481
+ } )
1482
+ . transpose ( ) ?;
1483
+ let tax = order
1484
+ . total_tax_amount
1485
+ . map ( |amount| {
1486
+ convert_amount ( NUVEI_AMOUNT_CONVERTOR , amount, currency)
1487
+ } )
1488
+ . transpose ( ) ?;
1489
+ Ok ( NuveiItem {
1490
+ name : order. product_name . clone ( ) ,
1491
+ item_type : order. product_type . clone ( ) . into ( ) ,
1492
+ price : convert_amount (
1493
+ NUVEI_AMOUNT_CONVERTOR ,
1494
+ order. amount ,
1495
+ currency,
1496
+ ) ?,
1497
+ quantity : order. quantity . to_string ( ) ,
1498
+ group_id : order. product_id . clone ( ) ,
1499
+ discount,
1500
+ discount_rate : None ,
1501
+ shipping : None ,
1502
+ shipping_tax : None ,
1503
+ shipping_tax_rate : None ,
1504
+ tax,
1505
+ tax_rate : order. tax_rate . map ( |rate| rate. to_string ( ) ) ,
1506
+ image_url : order. product_img_link . clone ( ) ,
1507
+ product_url : None ,
1508
+ } )
1509
+ } )
1510
+ . collect ( ) ;
1511
+ let mut items = Vec :: with_capacity ( results. len ( ) ) ;
1512
+ for result in results {
1513
+ match result {
1514
+ Ok ( item) => items. push ( item) ,
1515
+ Err ( err) => return Err ( err) ,
1516
+ }
1517
+ }
1518
+ Ok ( Some ( items) )
1519
+ } )
1520
+ } )
1521
+ }
1522
+
1523
+ fn get_amount_details (
1524
+ l2_l3_data : & Option < L2L3Data > ,
1525
+ currency : enums:: Currency ,
1526
+ ) -> Result < Option < NuveiAmountDetails > , error_stack:: Report < errors:: ConnectorError > > {
1527
+ l2_l3_data. as_ref ( ) . map_or ( Ok ( None ) , |data| {
1528
+ let total_tax = data
1529
+ . order_tax_amount
1530
+ . map ( |amount| convert_amount ( NUVEI_AMOUNT_CONVERTOR , amount, currency) )
1531
+ . transpose ( ) ?;
1532
+ let total_shipping = data
1533
+ . shipping_cost
1534
+ . map ( |amount| convert_amount ( NUVEI_AMOUNT_CONVERTOR , amount, currency) )
1535
+ . transpose ( ) ?;
1536
+ let total_discount = data
1537
+ . discount_amount
1538
+ . map ( |amount| convert_amount ( NUVEI_AMOUNT_CONVERTOR , amount, currency) )
1539
+ . transpose ( ) ?;
1540
+ let total_handling = data
1541
+ . duty_amount
1542
+ . map ( |amount| convert_amount ( NUVEI_AMOUNT_CONVERTOR , amount, currency) )
1543
+ . transpose ( ) ?;
1544
+ Ok ( Some ( NuveiAmountDetails {
1545
+ total_tax,
1546
+ total_shipping,
1547
+ total_handling,
1548
+ total_discount,
1549
+ } ) )
1550
+ } )
1551
+ }
1427
1552
1428
1553
impl < F , Req > TryFrom < ( & RouterData < F , Req , PaymentsResponseData > , String ) > for NuveiPaymentsRequest
1429
1554
where
@@ -1578,12 +1703,8 @@ where
1578
1703
} ) ?;
1579
1704
let return_url = item. request . get_return_url_required ( ) ?;
1580
1705
1581
- let amount_details = match item. request . get_order_tax_amount ( ) ? {
1582
- Some ( tax) => Some ( NuvieAmountDetails {
1583
- total_tax : Some ( convert_amount ( NUVEI_AMOUNT_CONVERTOR , tax, currency) ?) ,
1584
- } ) ,
1585
- None => None ,
1586
- } ;
1706
+ let amount_details = get_amount_details ( & item. l2_l3_data , currency) ?;
1707
+ let l2_l3_items: Option < Vec < NuveiItem > > = get_l2_l3_items ( & item. l2_l3_data , currency) ?;
1587
1708
let address = {
1588
1709
if let Some ( billing_address) = item. get_optional_billing ( ) {
1589
1710
let mut billing_address = billing_address. clone ( ) ;
@@ -1631,6 +1752,7 @@ where
1631
1752
pending_url : return_url. clone ( ) ,
1632
1753
} ) ,
1633
1754
amount_details,
1755
+ items : l2_l3_items,
1634
1756
is_partial_approval : item. request . get_is_partial_approval ( ) ,
1635
1757
..request
1636
1758
} )
@@ -3011,9 +3133,9 @@ fn convert_to_additional_payment_method_connector_response(
3011
3133
merchant_advice_code. and_then ( |code| get_merchant_advice_code_description ( code) ) ;
3012
3134
3013
3135
let payment_checks = serde_json:: json!( {
3014
- "avs_result_code " : avs_code,
3136
+ "avs_result " : avs_code,
3015
3137
"avs_description" : avs_description,
3016
- "cvv_2_reply_code " : cvv2_code,
3138
+ "cvv_2_reply " : cvv2_code,
3017
3139
"cvv_2_description" : cvv_description,
3018
3140
"merchant_advice_code" : merchant_advice_code,
3019
3141
"merchant_advice_code_description" : merchant_advice_description
0 commit comments