@@ -441,6 +441,8 @@ pub async fn add_payment_method_data(
441
441
status : Some ( enums:: PaymentMethodStatus :: Active ) ,
442
442
locker_id : Some ( locker_id) ,
443
443
payment_method : req. payment_method ,
444
+ payment_method_issuer : req. payment_method_issuer ,
445
+ payment_method_type : req. payment_method_type ,
444
446
} ;
445
447
446
448
db. update_payment_method (
@@ -555,7 +557,7 @@ pub async fn add_payment_method(
555
557
match duplication_check {
556
558
Some ( duplication_check) => match duplication_check {
557
559
payment_methods:: DataDuplicationCheck :: Duplicated => {
558
- get_or_insert_payment_method (
560
+ let existing_pm = get_or_insert_payment_method (
559
561
db,
560
562
req. clone ( ) ,
561
563
& mut resp,
@@ -564,6 +566,8 @@ pub async fn add_payment_method(
564
566
key_store,
565
567
)
566
568
. await ?;
569
+
570
+ resp. client_secret = existing_pm. client_secret ;
567
571
}
568
572
payment_methods:: DataDuplicationCheck :: MetaDataChanged => {
569
573
if let Some ( card) = req. card . clone ( ) {
@@ -577,6 +581,8 @@ pub async fn add_payment_method(
577
581
)
578
582
. await ?;
579
583
584
+ let client_secret = existing_pm. client_secret . clone ( ) ;
585
+
580
586
delete_card_from_locker (
581
587
& state,
582
588
& customer_id,
@@ -653,6 +659,8 @@ pub async fn add_payment_method(
653
659
. await
654
660
. change_context ( errors:: ApiErrorResponse :: InternalServerError )
655
661
. attach_printable ( "Failed to add payment method in db" ) ?;
662
+
663
+ resp. client_secret = client_secret;
656
664
}
657
665
}
658
666
} ,
@@ -667,7 +675,7 @@ pub async fn add_payment_method(
667
675
None
668
676
} ;
669
677
resp. payment_method_id = generate_id ( consts:: ID_LENGTH , "pm" ) ;
670
- insert_payment_method (
678
+ let pm = insert_payment_method (
671
679
db,
672
680
& resp,
673
681
req,
@@ -682,6 +690,8 @@ pub async fn add_payment_method(
682
690
merchant_account. storage_scheme ,
683
691
)
684
692
. await ?;
693
+
694
+ resp. client_secret = pm. client_secret ;
685
695
}
686
696
}
687
697
@@ -744,6 +754,18 @@ pub async fn update_customer_payment_method(
744
754
. await
745
755
. to_not_found_response ( errors:: ApiErrorResponse :: PaymentMethodNotFound ) ?;
746
756
757
+ if pm. status == enums:: PaymentMethodStatus :: AwaitingData {
758
+ return Err ( report ! ( errors:: ApiErrorResponse :: NotSupported {
759
+ message: "Payment method is awaiting data so it cannot be updated" . into( )
760
+ } ) ) ;
761
+ }
762
+
763
+ if pm. payment_method_data . is_none ( ) {
764
+ return Err ( report ! ( errors:: ApiErrorResponse :: GenericNotFoundError {
765
+ message: "payment_method_data not found" . to_string( )
766
+ } ) ) ;
767
+ }
768
+
747
769
// Fetch the existing payment method data from db
748
770
let existing_card_data = decrypt :: < serde_json:: Value , masking:: WithType > (
749
771
pm. payment_method_data . clone ( ) ,
@@ -812,7 +834,7 @@ pub async fn update_customer_payment_method(
812
834
wallet : req. wallet ,
813
835
metadata : req. metadata ,
814
836
customer_id : Some ( pm. customer_id . clone ( ) ) ,
815
- client_secret : None ,
837
+ client_secret : pm . client_secret . clone ( ) ,
816
838
payment_method_data : None ,
817
839
card_network : req
818
840
. card_network
@@ -901,7 +923,7 @@ pub async fn update_customer_payment_method(
901
923
installment_payment_enabled : false ,
902
924
payment_experience : Some ( vec ! [ api_models:: enums:: PaymentExperience :: RedirectToUrl ] ) ,
903
925
last_used_at : Some ( common_utils:: date_time:: now ( ) ) ,
904
- client_secret : None ,
926
+ client_secret : pm . client_secret . clone ( ) ,
905
927
}
906
928
} ;
907
929
@@ -1691,12 +1713,21 @@ pub async fn list_payment_methods(
1691
1713
let db = & * state. store ;
1692
1714
let pm_config_mapping = & state. conf . pm_filters ;
1693
1715
1694
- let payment_intent = helpers:: verify_payment_intent_time_and_client_secret (
1695
- db,
1696
- & merchant_account,
1697
- req. client_secret . clone ( ) ,
1698
- )
1699
- . await ?;
1716
+ let payment_intent = if let Some ( cs) = & req. client_secret {
1717
+ if cs. starts_with ( "pm_" ) {
1718
+ validate_payment_method_and_client_secret ( cs, db, & merchant_account) . await ?;
1719
+ None
1720
+ } else {
1721
+ helpers:: verify_payment_intent_time_and_client_secret (
1722
+ db,
1723
+ & merchant_account,
1724
+ req. client_secret . clone ( ) ,
1725
+ )
1726
+ . await ?
1727
+ }
1728
+ } else {
1729
+ None
1730
+ } ;
1700
1731
1701
1732
let shipping_address = payment_intent
1702
1733
. as_ref ( )
@@ -1839,6 +1870,7 @@ pub async fn list_payment_methods(
1839
1870
pm_config_mapping,
1840
1871
& state. conf . mandates . supported_payment_methods ,
1841
1872
& state. conf . mandates . update_mandate_supported ,
1873
+ & state. conf . saved_payment_methods ,
1842
1874
)
1843
1875
. await ?;
1844
1876
}
@@ -2535,6 +2567,34 @@ pub async fn list_payment_methods(
2535
2567
) )
2536
2568
}
2537
2569
2570
+ async fn validate_payment_method_and_client_secret (
2571
+ cs : & String ,
2572
+ db : & dyn db:: StorageInterface ,
2573
+ merchant_account : & domain:: MerchantAccount ,
2574
+ ) -> Result < ( ) , error_stack:: Report < errors:: ApiErrorResponse > > {
2575
+ let pm_vec = cs. split ( "_secret" ) . collect :: < Vec < & str > > ( ) ;
2576
+ let pm_id = pm_vec
2577
+ . first ( )
2578
+ . ok_or ( errors:: ApiErrorResponse :: MissingRequiredField {
2579
+ field_name : "client_secret" ,
2580
+ } ) ?;
2581
+
2582
+ let payment_method = db
2583
+ . find_payment_method ( pm_id, merchant_account. storage_scheme )
2584
+ . await
2585
+ . change_context ( errors:: ApiErrorResponse :: PaymentMethodNotFound )
2586
+ . attach_printable ( "Unable to find payment method" ) ?;
2587
+
2588
+ let client_secret_expired =
2589
+ authenticate_pm_client_secret_and_check_expiry ( cs, & payment_method) ?;
2590
+ if client_secret_expired {
2591
+ return Err :: < ( ) , error_stack:: Report < errors:: ApiErrorResponse > > (
2592
+ ( errors:: ApiErrorResponse :: ClientSecretExpired ) . into ( ) ,
2593
+ ) ;
2594
+ }
2595
+ Ok ( ( ) )
2596
+ }
2597
+
2538
2598
pub async fn call_surcharge_decision_management (
2539
2599
state : routes:: AppState ,
2540
2600
merchant_account : & domain:: MerchantAccount ,
@@ -2644,6 +2704,7 @@ pub async fn filter_payment_methods(
2644
2704
config : & settings:: ConnectorFilters ,
2645
2705
supported_payment_methods_for_mandate : & settings:: SupportedPaymentMethodsForMandate ,
2646
2706
supported_payment_methods_for_update_mandate : & settings:: SupportedPaymentMethodsForMandate ,
2707
+ saved_payment_methods : & settings:: EligiblePaymentMethods ,
2647
2708
) -> errors:: CustomResult < ( ) , errors:: ApiErrorResponse > {
2648
2709
for payment_method in payment_methods. into_iter ( ) {
2649
2710
let parse_result = serde_json:: from_value :: < PaymentMethodsEnabled > ( payment_method) ;
@@ -2761,6 +2822,20 @@ pub async fn filter_payment_methods(
2761
2822
} )
2762
2823
. unwrap_or ( true ) ;
2763
2824
2825
+ let filter9 = req
2826
+ . client_secret
2827
+ . as_ref ( )
2828
+ . map ( |cs| {
2829
+ if cs. starts_with ( "pm_" ) {
2830
+ saved_payment_methods
2831
+ . sdk_eligible_payment_methods
2832
+ . contains ( payment_method. to_string ( ) . as_str ( ) )
2833
+ } else {
2834
+ true
2835
+ }
2836
+ } )
2837
+ . unwrap_or ( true ) ;
2838
+
2764
2839
let connector = connector. clone ( ) ;
2765
2840
2766
2841
let response_pm_type = ResponsePaymentMethodIntermediate :: new (
@@ -2777,6 +2852,7 @@ pub async fn filter_payment_methods(
2777
2852
&& filter6
2778
2853
&& filter7
2779
2854
&& filter8
2855
+ && filter9
2780
2856
{
2781
2857
resp. push ( response_pm_type) ;
2782
2858
}
0 commit comments