Skip to content

Commit

Permalink
Merge pull request #673 from braintree/samsung_pay_support_single_use…
Browse files Browse the repository at this point in the history
…_token

Support SamsungPay Single Use Token
  • Loading branch information
sshropshire authored Feb 6, 2023
2 parents 3323189 + ad1a37a commit a4c1f19
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
* Fixes bug in `PayPalNativeCheckoutAccountNonce` where the `intent` was not being set correctly from the `PayPalNativeCheckoutRequest`
* ThreeDSecure
* Apply `Theme.AppCompat` to `ThreeDSecureActivity`
* SamsungPay
* Support legacy `singleUseToken` property when parsing Samsung Pay response (fixes #668)

## 4.24.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

/**
* {@link PaymentMethodNonce} representing a Samsung Pay card.
*
* @see PaymentMethodNonce
*/
public class SamsungPayNonce extends PaymentMethodNonce {
Expand All @@ -22,9 +23,14 @@ static SamsungPayNonce fromJSON(JSONObject inputJson) throws JSONException {
JSONObject data = new JSONObject(inputJson.getString("data"));
JSONObject braintreeData = new JSONObject(data.getString("data"));

JSONObject paymentMethod = braintreeData
.getJSONObject("tokenizeSamsungPayCard")
.getJSONObject("paymentMethod");
JSONObject tokenizeSamsungPayResponse =
braintreeData.getJSONObject("tokenizeSamsungPayCard");

JSONObject paymentMethod = tokenizeSamsungPayResponse.optJSONObject("paymentMethod");
if (paymentMethod == null) {
// fallback to single use token key; throws when fallback not present
paymentMethod = tokenizeSamsungPayResponse.getJSONObject("singleUseToken");
}

String nonce = paymentMethod.getString("id");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ public void startSamsungPay_onCardInfoUpdated_updatesPaymentManagerSheetAndNotif
public void startSamsungPay_onSuccess_notifiesListenerOfNonceCreation() {
CustomSheetPaymentInfo customSheetPaymentInfo = mock(CustomSheetPaymentInfo.class);
PaymentManager paymentManager = new MockPaymentManagerBuilder()
.startInAppPayWithCustomSheetSuccess(customSheetPaymentInfo, Fixtures.SAMSUNG_PAY_RESPONSE)
.startInAppPayWithCustomSheetSuccess(customSheetPaymentInfo, Fixtures.SAMSUNG_PAY_RESPONSE_V2)
.build();

SamsungPay samsungPay = mock(SamsungPay.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
package com.braintreepayments.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;

import static org.junit.Assert.*;

public class SamsungPayNonceUnitTest {

@Test
public void fromJSON_parsesNonce() throws JSONException {
SamsungPayNonce sut = SamsungPayNonce.fromJSON(new JSONObject(Fixtures.SAMSUNG_PAY_RESPONSE));
public void fromJSON_parsesNonce_v2() throws JSONException {
SamsungPayNonce sut = SamsungPayNonce.fromJSON(new JSONObject(Fixtures.SAMSUNG_PAY_RESPONSE_V2));

assertEquals("tokensam_bf_v8s9hv_2htw4m_nh4f45_y3hsft_wty", sut.getString());
assertFalse(sut.isDefault());

assertEquals("Mastercard", sut.getCardType());
assertEquals("1798", sut.getLastFour());

BinData binData = sut.getBinData();
assertEquals("Unknown", binData.getPrepaid());
assertEquals("Yes", binData.getHealthcare());
assertEquals("No", binData.getDebit());
assertEquals("Unknown", binData.getDurbinRegulated());
assertEquals("Unknown", binData.getCommercial());
assertEquals("Unknown", binData.getPayroll());
assertEquals("Unknown", binData.getIssuingBank());
assertEquals("US", binData.getCountryOfIssuance());
assertEquals("123", binData.getProductId());
}

@Test
public void fromJSON_parsesNonce_v1() throws JSONException {
SamsungPayNonce sut = SamsungPayNonce.fromJSON(new JSONObject(Fixtures.SAMSUNG_PAY_RESPONSE_V1));

assertEquals("tokensam_bf_v8s9hv_2htw4m_nh4f45_y3hsft_wty", sut.getString());
assertFalse(sut.isDefault());
Expand Down
23 changes: 22 additions & 1 deletion TestUtils/src/main/java/com/braintreepayments/api/Fixtures.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2474,7 +2474,7 @@ object Fixtures {
//endregion

// language=JSON
const val SAMSUNG_PAY_RESPONSE = """
const val SAMSUNG_PAY_RESPONSE_V2 = """
{
"data": "{\n \"data\": {\n \"tokenizeSamsungPayCard\": {\n \"paymentMethod\": {\n \"id\": \"tokensam_bf_v8s9hv_2htw4m_nh4f45_y3hsft_wty\",\n \"details\": {\n \"brand\": \"Mastercard\",\n \"brandCode\": \"MASTERCARD\",\n \"last4\": \"1798\",\n \"expirationYear\": \"2020\",\n \"expirationMonth\": \"12\",\n \"binData\": {\n \"commercial\": \"UNKNOWN\",\n \"countryOfIssuance\": \"US\",\n \"debit\": \"NO\",\n \"durbinRegulated\": \"UNKNOWN\",\n \"healthcare\": \"YES\",\n \"issuingBank\": null,\n \"payroll\": \"UNKNOWN\",\n \"prepaid\": \"UNKNOWN\",\n \"productId\": \"123\"\n },\n \"origin\": {\n \"type\": \"SAMSUNG_PAY\",\n \"details\": {\n \"bin\": \"411111\"\n }\n }\n }\n }\n }\n },\n \"extensions\": {\n \"requestId\": \"9eaf90d9-4e8a-4883-96c4-01c02bb0a4e5\"\n }\n}",
"reference":"tokensam_bf_v8s9hv_2htw4m_nh4f45_y3hsft_wty",
Expand All @@ -2493,6 +2493,27 @@ object Fixtures {
}
"""

// NOTE: SamsungPay response sometimes has `singleUseToken` as an alias for the top level `paymentMethod` field
// language=JSON
const val SAMSUNG_PAY_RESPONSE_V1 = """
{
"data": "{\n \"data\": {\n \"tokenizeSamsungPayCard\": {\n \"singleUseToken\": {\n \"id\": \"tokensam_bf_v8s9hv_2htw4m_nh4f45_y3hsft_wty\",\n \"details\": {\n \"brand\": \"Mastercard\",\n \"brandCode\": \"MASTERCARD\",\n \"last4\": \"1798\",\n \"expirationYear\": \"2020\",\n \"expirationMonth\": \"12\",\n \"binData\": {\n \"commercial\": \"UNKNOWN\",\n \"countryOfIssuance\": \"US\",\n \"debit\": \"NO\",\n \"durbinRegulated\": \"UNKNOWN\",\n \"healthcare\": \"YES\",\n \"issuingBank\": null,\n \"payroll\": \"UNKNOWN\",\n \"prepaid\": \"UNKNOWN\",\n \"productId\": \"123\"\n },\n \"origin\": {\n \"type\": \"SAMSUNG_PAY\",\n \"details\": {\n \"bin\": \"411111\"\n }\n }\n }\n }\n }\n },\n \"extensions\": {\n \"requestId\": \"9eaf90d9-4e8a-4883-96c4-01c02bb0a4e5\"\n }\n}",
"reference":"tokensam_bf_v8s9hv_2htw4m_nh4f45_y3hsft_wty",
"status":"AUTHORIZED",
"payment_last4_dpan":"1798",
"payment_last4_fpan":"1470",
"payment_card_brand":"MC",
"payment_currency_type":"USD",
"payment_shipping_address":{
"shipping":{
},
"email":""
},
"payment_shipping_method":""
}
"""

//region SEPA Debit

// language=JSON
Expand Down

0 comments on commit a4c1f19

Please sign in to comment.