@@ -28,15 +28,24 @@ class FraudProcessorResponse {
2828 */
2929 protected string $ cvv2_code ;
3030
31+ /**
32+ * The processor response code (e.g. 9500, 9100).
33+ *
34+ * @var string
35+ */
36+ protected string $ response_code ;
37+
3138 /**
3239 * FraudProcessorResponse constructor.
3340 *
3441 * @param string|null $avs_code The AVS response code.
3542 * @param string|null $cvv2_code The CVV response code.
43+ * @param string|null $response_code The processor response code.
3644 */
37- public function __construct ( ?string $ avs_code , ?string $ cvv2_code ) {
38- $ this ->avs_code = (string ) $ avs_code ;
39- $ this ->cvv2_code = (string ) $ cvv2_code ;
45+ public function __construct ( ?string $ avs_code , ?string $ cvv2_code , ?string $ response_code = null ) {
46+ $ this ->avs_code = (string ) $ avs_code ;
47+ $ this ->cvv2_code = (string ) $ cvv2_code ;
48+ $ this ->response_code = (string ) $ response_code ;
4049 }
4150
4251 /**
@@ -57,15 +66,25 @@ public function cvv_code(): string {
5766 return $ this ->cvv2_code ;
5867 }
5968
69+ /**
70+ * Returns the processor response code.
71+ *
72+ * @return string
73+ */
74+ public function response_code (): string {
75+ return $ this ->response_code ;
76+ }
77+
6078 /**
6179 * Returns the object as array.
6280 *
6381 * @return array
6482 */
6583 public function to_array (): array {
6684 return array (
67- 'avs_code ' => $ this ->avs_code (),
68- 'cvv2_code ' => $ this ->cvv_code (),
85+ 'avs_code ' => $ this ->avs_code (),
86+ 'cvv2_code ' => $ this ->cvv_code (),
87+ 'response_code ' => $ this ->response_code (),
6988 );
7089 }
7190
@@ -155,4 +174,87 @@ public function get_cvv2_code_message(): string {
155174 */
156175 return $ messages [ $ this ->cvv_code () ] ?? sprintf ( '%s: Error ' , $ this ->cvv_code () );
157176 }
177+
178+ /**
179+ * Returns the customer-facing decline message, including the processor response code when available.
180+ *
181+ * @return string
182+ */
183+ public function get_customer_decline_message (): string {
184+ if ( $ this ->response_code () ) {
185+ return sprintf (
186+ /* translators: %s - processor response code and description */
187+ __ ( 'Payment declined by card processor: %s. Please use a different payment method or contact your bank. ' , 'woocommerce-paypal-payments ' ),
188+ $ this ->get_response_code_message ()
189+ );
190+ }
191+
192+ return __ ( 'Payment provider declined the payment, please use a different payment method. ' , 'woocommerce-paypal-payments ' );
193+ }
194+
195+ /**
196+ * Returns the human-readable description for the processor response code.
197+ *
198+ * @return string
199+ */
200+ public function get_response_code_message (): string {
201+ if ( ! $ this ->response_code () ) {
202+ return '' ;
203+ }
204+ $ messages = array (
205+ '0000 ' => '0000: Approved ' ,
206+ '00N7 ' => '00N7: Decline CVV2 Failure ' ,
207+ '0100 ' => '0100: Refer to card issuer ' ,
208+ '0390 ' => '0390: No credit account ' ,
209+ '0500 ' => '0500: Do not honor ' ,
210+ '0580 ' => '0580: Transaction not permitted to cardholder ' ,
211+ '0800 ' => '0800: Bad response reversal amount ' ,
212+ '0880 ' => '0880: Cryptographic failure ' ,
213+ '0890 ' => '0890: Unavailable ' ,
214+ '0960 ' => '0960: System malfunction ' ,
215+ '1000 ' => '1000: Partial Approval ' ,
216+ '10BR ' => '10BR: 3DS Authentication Failure ' ,
217+ '1300 ' => '1300: Invalid data format ' ,
218+ '1310 ' => '1310: Invalid amount ' ,
219+ '1312 ' => '1312: Invalid transaction card issuer acquirer ' ,
220+ '1317 ' => '1317: Invalid capture date ' ,
221+ '1320 ' => '1320: Invalid currency code ' ,
222+ '1330 ' => '1330: Invalid account ' ,
223+ '1335 ' => '1335: Invalid account type ' ,
224+ '1340 ' => '1340: Invalid terminal id ' ,
225+ '1350 ' => '1350: Invalid merchant/terminal city ' ,
226+ '1360 ' => '1360: Bad or malformed request ' ,
227+ '1370 ' => '1370: Issuer unavailable ' ,
228+ '1380 ' => '1380: Updates not allowed ' ,
229+ '1382 ' => '1382: Bad CVV2 ' ,
230+ '1384 ' => '1384: Similar transaction recently submitted ' ,
231+ '1390 ' => '1390: Trace number error ' ,
232+ '1393 ' => '1393: Transaction amount range error ' ,
233+ '5100 ' => '5100: Generic Decline ' ,
234+ '5110 ' => '5110: CVV2 Failure ' ,
235+ '5120 ' => '5120: Insufficient funds ' ,
236+ '5130 ' => '5130: Invalid PIN ' ,
237+ '5140 ' => '5140: Card closed ' ,
238+ '5150 ' => '5150: Pick up card (fraud) ' ,
239+ '5160 ' => '5160: Unauthorized user ' ,
240+ '5170 ' => '5170: Card blocked ' ,
241+ '5180 ' => '5180: Declined by the issuer ' ,
242+ '5200 ' => '5200: Account closed ' ,
243+ '5400 ' => '5400: Expired card ' ,
244+ '5910 ' => '5910: Issuer not available, return to issuer ' ,
245+ '5920 ' => '5920: Issuer not available, return to issuer ' ,
246+ '5930 ' => '5930: Card not activated ' ,
247+ '6300 ' => '6300: Account blocked ' ,
248+ '9100 ' => '9100: Declined, Please Retry ' ,
249+ '9500 ' => '9500: Suspected Fraud ' ,
250+ '9510 ' => '9510: Security Violation ' ,
251+ '9520 ' => '9520: Lost or Stolen Card ' ,
252+ '9530 ' => '9530: Hold - Call issuer ' ,
253+ '9540 ' => '9540: Refused Card ' ,
254+ '9600 ' => '9600: Unacceptable PIN - Transaction Declined - Retry ' ,
255+ 'PCNF ' => 'PCNF: Purchase Confirmation Not Received ' ,
256+ 'PCOM ' => 'PCOM: Purchase Confirmation Received ' ,
257+ );
258+ return $ messages [ $ this ->response_code () ] ?? sprintf ( '%s: Unknown response code ' , $ this ->response_code () );
259+ }
158260}
0 commit comments