Skip to content

Commit cc88a80

Browse files
feature/INT-1724 - CashApp payment method integration (#686)
* feat(payment-setups): add device fingerprint, ip, client and os fields customer.device gains fingerprint, ipv4, ipv6, client (web, mobile_web, app) and os (android, ios). The client is required by Cash App. * feat(payment-setups): add Cash App Pay payment method Adds payment_methods.cashapp with customer_profile_sharing and the read-only customer_profile, reference and action (redirect_url). The key is pinned with SerializedName so the global underscore naming policy cannot turn it into cash_app. Tests use the SDK serializer to assert the wire format. * CashApp review and tests --------- Co-authored-by: Armando Rodríguez <127134616+armando-rodriguez-cko@users.noreply.github.com>
1 parent 491eb58 commit cc88a80

16 files changed

Lines changed: 950 additions & 13 deletions
Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.checkout.handlepaymentsandpayouts.setups.entities.customer;
22

3+
import com.checkout.common.CountryCode;
34
import com.checkout.common.Phone;
45
import lombok.AllArgsConstructor;
56
import lombok.Builder;
67
import lombok.Data;
78
import lombok.NoArgsConstructor;
89

910
/**
10-
* Customer information for payment setup
11+
* The customer's details.
1112
*/
1213
@Data
1314
@Builder
@@ -16,28 +17,52 @@
1617
public final class Customer {
1718

1819
/**
19-
* The customer's email information
20+
* Details of the customer's email.
21+
* [Optional]
2022
*/
2123
private CustomerEmail email;
2224

2325
/**
24-
* &lt;= 100 characters
25-
* The customer's full name
26+
* The customer's full name.
27+
* [Optional]
28+
* max 100 characters
2629
*/
2730
private String name;
2831

2932
/**
30-
* The customer's phone number
33+
* The customer's phone number.
34+
* [Optional]
3135
*/
3236
private Phone phone;
3337

3438
/**
35-
* Information about the customer's device
39+
* Details of the customer's device.
40+
* [Optional]
3641
*/
3742
private CustomerDevice device;
3843

3944
/**
40-
* Details of the account the customer holds with the merchant
45+
* Details of the account the customer holds with the merchant.
46+
* [Optional]
4147
*/
4248
private MerchantAccount merchantAccount;
43-
}
49+
50+
/**
51+
* The unique identifier of the customer.
52+
* [Optional]
53+
*/
54+
private String id;
55+
56+
/**
57+
* The two-letter ISO country code of the customer for this payment.
58+
* [Optional]
59+
* min 2 characters, max 2 characters
60+
*/
61+
private CountryCode country;
62+
63+
/**
64+
* The customer's tax identification number.
65+
* [Optional]
66+
*/
67+
private String taxNumber;
68+
}
Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package com.checkout.handlepaymentsandpayouts.setups.entities.customer;
22

3+
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.common.OsType;
34
import lombok.AllArgsConstructor;
45
import lombok.Builder;
56
import lombok.Data;
67
import lombok.NoArgsConstructor;
78

89
/**
9-
* Customer device information
10+
* Details of the customer's device.
1011
*/
1112
@Data
1213
@Builder
@@ -15,7 +16,41 @@
1516
public final class CustomerDevice {
1617

1718
/**
18-
* The locale setting of the customer's device (e.g., "en-US")
19+
* The locale of the device, for example en_GB.
20+
* [Optional]
1921
*/
2022
private String locale;
21-
}
23+
24+
/**
25+
* A unique identifier for the customer's device.
26+
* [Optional]
27+
*/
28+
private String fingerprint;
29+
30+
/**
31+
* The customer's device IPv4 address, used by some payment methods for risk and eligibility checks.
32+
* [Optional]
33+
*/
34+
private String ipv4;
35+
36+
/**
37+
* The customer's device IPv6 address, used by some payment methods for risk and eligibility checks.
38+
* [Optional]
39+
*/
40+
private String ipv6;
41+
42+
/**
43+
* The type of client the customer uses to initiate the payment. Required when using Cash App
44+
* Pay; a Cash App payment setup without it is rejected.
45+
* [Optional]
46+
* Enum: "web" "mobile_web" "app"
47+
*/
48+
private CustomerDeviceClient client;
49+
50+
/**
51+
* The operating system of the customer's device.
52+
* [Optional]
53+
* Enum: "android" "ios"
54+
*/
55+
private OsType os;
56+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.checkout.handlepaymentsandpayouts.setups.entities.customer;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
/**
6+
* The type of client the customer uses to initiate the payment.
7+
*/
8+
public enum CustomerDeviceClient {
9+
10+
/**
11+
* A web browser on a desktop device.
12+
*/
13+
@SerializedName("web")
14+
WEB,
15+
16+
/**
17+
* A web browser on a mobile device.
18+
*/
19+
@SerializedName("mobile_web")
20+
MOBILE_WEB,
21+
22+
/**
23+
* A native mobile application.
24+
*/
25+
@SerializedName("app")
26+
APP
27+
}

‎src/main/java/com/checkout/handlepaymentsandpayouts/setups/entities/paymentMethods/PaymentMethods.java‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.blik.Blik;
1313
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.card.Card;
1414
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.cardpresent.CardPresent;
15+
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.cashapp.CashApp;
1516
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.paybybank.PayByBank;
1617
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.stablecoin.Stablecoin;
1718
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.dana.Dana;
@@ -307,4 +308,12 @@ public final class PaymentMethods {
307308
* [Optional]
308309
*/
309310
private Stablecoin stablecoin;
311+
312+
/**
313+
* The Cash App Pay payment method's details and configuration. The wire key is the single
314+
* word cashapp, so keep this field name lowercase: the naming policy turns cashApp into
315+
* cash_app.
316+
* [Optional]
317+
*/
318+
private CashApp cashapp;
310319
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.cashapp;
2+
3+
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.common.PaymentMethodBase;
4+
import com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.common.PaymentMethodInitialization;
5+
import lombok.Data;
6+
import lombok.EqualsAndHashCode;
7+
8+
/**
9+
* Cash App Pay payment method configuration. The customer must be sent to the redirect URL
10+
* returned in the action to authorize the payment with Cash App. The payment setup customer
11+
* device client is required for this method.
12+
*/
13+
@Data
14+
@EqualsAndHashCode(callSuper = true)
15+
public final class CashApp extends PaymentMethodBase {
16+
17+
/**
18+
* The initialization state of the payment method. Defaults to disabled.
19+
* [Optional]
20+
*/
21+
private PaymentMethodInitialization initialization = PaymentMethodInitialization.DISABLED;
22+
23+
/**
24+
* Indicates whether the customer consents to share their Cash App customer profile with
25+
* Checkout.com. When enabled, the customer profile is returned once, after the customer
26+
* authorizes the payment.
27+
* [Optional]
28+
*/
29+
private Boolean customerProfileSharing;
30+
31+
/**
32+
* The customer's Cash App profile that they consented to share. Included in the response when
33+
* customer_profile_sharing is enabled. Cash App releases this profile only once: it is present
34+
* in the first successful response when you get the payment setup after the customer
35+
* authorizes the payment, and every subsequent response omits it, so store it on first read.
36+
* [Optional] readOnly
37+
*/
38+
private CashAppCustomerProfile customerProfile;
39+
40+
/**
41+
* A reference for the Cash App Pay transaction, returned by the provider.
42+
* [Optional] readOnly
43+
* max 80 characters
44+
*/
45+
private String reference;
46+
47+
/**
48+
* The next available action for the payment method. When its type is redirect, send the
49+
* customer to its redirect URL to authorize the payment with Cash App.
50+
* [Optional] readOnly
51+
*/
52+
private CashAppAction action;
53+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.cashapp;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
/**
9+
* The next available action for the Cash App payment method.
10+
*/
11+
@Data
12+
@Builder
13+
@NoArgsConstructor
14+
@AllArgsConstructor
15+
public final class CashAppAction {
16+
17+
/**
18+
* The type of action.
19+
* [Optional] readOnly
20+
* Enum: "redirect"
21+
*/
22+
private CashAppActionType type;
23+
24+
/**
25+
* The URL to redirect the customer to so they can authorize the payment with Cash App.
26+
* [Optional] readOnly
27+
* Format: uri
28+
*/
29+
private String redirectUrl;
30+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.cashapp;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
/**
6+
* The type of next action for the Cash App payment method.
7+
*/
8+
public enum CashAppActionType {
9+
10+
/**
11+
* Redirect the customer to Cash App to authorize the payment.
12+
*/
13+
@SerializedName("redirect")
14+
REDIRECT
15+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.checkout.handlepaymentsandpayouts.setups.entities.paymentMethods.cashapp;
2+
3+
import com.checkout.common.CountryCode;
4+
import com.google.gson.annotations.SerializedName;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.NoArgsConstructor;
9+
10+
/**
11+
* The customer's address from their Cash App profile. The keys follow Cash App's naming
12+
* (address_line_1, locality, administrative_district_level_1), not the Checkout.com address, so
13+
* the line and district fields carry an explicit serialized name: the naming policy alone would
14+
* produce address_line1.
15+
*/
16+
@Data
17+
@Builder
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
public final class CashAppAddress {
21+
22+
/**
23+
* The first line of the address.
24+
* [Optional] readOnly
25+
*/
26+
@SerializedName("address_line_1")
27+
private String addressLine1;
28+
29+
/**
30+
* The second line of the address.
31+
* [Optional] readOnly
32+
*/
33+
@SerializedName("address_line_2")
34+
private String addressLine2;
35+
36+
/**
37+
* The third line of the address.
38+
* [Optional] readOnly
39+
*/
40+
@SerializedName("address_line_3")
41+
private String addressLine3;
42+
43+
/**
44+
* The address locality, such as the city or town.
45+
* [Optional] readOnly
46+
*/
47+
private String locality;
48+
49+
/**
50+
* The address sublocality, such as the district or neighborhood.
51+
* [Optional] readOnly
52+
*/
53+
private String sublocality;
54+
55+
/**
56+
* The address's top-level administrative district, such as the state or province.
57+
* [Optional] readOnly
58+
*/
59+
@SerializedName("administrative_district_level_1")
60+
private String administrativeDistrictLevel1;
61+
62+
/**
63+
* The postal or zip code.
64+
* [Optional] readOnly
65+
*/
66+
private String postalCode;
67+
68+
/**
69+
* The address country, in ISO 3166-1 alpha-2 format.
70+
* [Optional] readOnly
71+
* max 2 characters
72+
*/
73+
private CountryCode country;
74+
}

0 commit comments

Comments
 (0)