Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds applepay and googlepay support #102

Merged
merged 2 commits into from Apr 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -26,7 +26,7 @@
<groupId>org.kill-bill.billing.plugin.java</groupId>
<artifactId>adyen-plugin</artifactId>
<name>Kill Bill OSGI Adyen plugin</name>
<version>0.5.15</version>
<version>0.5.16-SNAPSHOT</version>
<packaging>bundle</packaging>
<description>Kill Bill Adyen plugin</description>
<url>http://github.com/killbill/killbill-adyen-plugin</url>
Expand Down
Expand Up @@ -134,6 +134,19 @@ private static void set3DSecureFields(final PaymentInfo paymentInfo, final Itera
final String mpiDataAuthenticationResponse = PluginProperties.findPluginPropertyValue(PROPERTY_MPI_DATA_AUTHENTICATION_RESPONSE, properties);
paymentInfo.setMpiDataAuthenticationResponse(mpiDataAuthenticationResponse);

final String mpiDataEci = PluginProperties.findPluginPropertyValue(PROPERTY_MPI_DATA_ECI, properties);
paymentInfo.setMpiDataEci(mpiDataEci);

final String selectedBrand = PluginProperties.findPluginPropertyValue(PROPERTY_SELECTED_BRAND, properties);

if (selectedBrand != null) {
paymentInfo.setMpiDataDirectoryResponse("Y");
paymentInfo.setMpiDataAuthenticationResponse("Y");
if (mpiDataEci == null || mpiDataEci.isEmpty()) {
paymentInfo.setMpiDataEci("7");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected the brand overrides this value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Adyen asked to send these values.

}
}

final String mpiDataCavv = PluginProperties.findPluginPropertyValue(PROPERTY_MPI_DATA_CAVV, properties);
paymentInfo.setMpiDataCavv(mpiDataCavv);

Expand All @@ -143,9 +156,6 @@ private static void set3DSecureFields(final PaymentInfo paymentInfo, final Itera
final String mpiDataXid = PluginProperties.findPluginPropertyValue(PROPERTY_MPI_DATA_XID, properties);
paymentInfo.setMpiDataXid(mpiDataXid);

final String mpiDataEci = PluginProperties.findPluginPropertyValue(PROPERTY_MPI_DATA_ECI, properties);
paymentInfo.setMpiDataEci(mpiDataEci);

final String mpiImplementationType = PluginProperties.findPluginPropertyValue(PROPERTY_MPI_IMPLEMENTATION_TYPE, properties);
paymentInfo.setMpiImplementationType(mpiImplementationType);
if (mpiImplementationType != null) {
Expand Down
Expand Up @@ -134,13 +134,16 @@ private void set3DSecureFields() {
final BigDecimal amount = paymentData.getAmount();
final PaymentInfo paymentInfo = paymentData.getPaymentInfo();

boolean thresholdReached = false;
if (amount != null && paymentInfo.getThreeDThreshold() != null) {
final Long amountMinorUnits = toMinorUnits(amount, paymentData.getCurrency().name());
thresholdReached = amountMinorUnits.compareTo(paymentInfo.getThreeDThreshold()) >= 0;
}
if (!thresholdReached) {
return;
// applepay and googlepay require mpidata
if (paymentInfo.getSelectedBrand() == null) {
boolean thresholdReached = false;
if (amount != null && paymentInfo.getThreeDThreshold() != null) {
final Long amountMinorUnits = toMinorUnits(amount, paymentData.getCurrency().name());
thresholdReached = amountMinorUnits.compareTo(paymentInfo.getThreeDThreshold()) >= 0;
}
if (!thresholdReached) {
return;
}
}

final BrowserInfo browserInfo = new BrowserInfo();
Expand Down
Expand Up @@ -107,6 +107,30 @@ public class TestAdyenPaymentPluginApi extends TestAdyenPaymentPluginApiBase {
.put(AdyenPaymentPluginApi.PROPERTY_TERM_URL, "dummy://url")
.put(AdyenPaymentPluginApi.PROPERTY_THREE_D_THRESHOLD, "25000")
.build());
private final Iterable<PluginProperty> propertiesWithGooglePay = PluginProperties.buildPluginProperties(ImmutableMap.<String, String>builder()
.put(AdyenPaymentPluginApi.PROPERTY_CC_LAST_NAME, "Googlepaytester")
.put(AdyenPaymentPluginApi.PROPERTY_SELECTED_BRAND, "paywithgoogle")
.put(AdyenPaymentPluginApi.PROPERTY_MPI_DATA_CAVV, "AAAAAAAAt5fMJPDr320qAAALwwA=hq0BA9EAAAGXIJcAGAAAABKU0+s=")
.put(AdyenPaymentPluginApi.PROPERTY_MPI_DATA_ECI, "7")
.put(AdyenPaymentPluginApi.PROPERTY_CC_NUMBER, CC_3DS_NUMBER)
.put(AdyenPaymentPluginApi.PROPERTY_CC_EXPIRATION_MONTH, "10")
.put(AdyenPaymentPluginApi.PROPERTY_CC_EXPIRATION_YEAR, "2020")
.put(AdyenPaymentPluginApi.PROPERTY_USER_AGENT, "Java/1.8")
.put(AdyenPaymentPluginApi.PROPERTY_ACCEPT_HEADER, "application/json")
.put(AdyenPaymentPluginApi.PROPERTY_TERM_URL, "dummy://url")
.build());
private final Iterable<PluginProperty> propertiesWithApplePay = PluginProperties.buildPluginProperties(ImmutableMap.<String, String>builder()
.put(AdyenPaymentPluginApi.PROPERTY_CC_LAST_NAME, "Applepaytester")
.put(AdyenPaymentPluginApi.PROPERTY_SELECTED_BRAND, "applepay")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test with brand and without eci to verify the logic?

.put(AdyenPaymentPluginApi.PROPERTY_MPI_DATA_CAVV, "AAAAAAAAt5fMJPDr320qAAALwwA=hq0BA9EAAAGXIJcAGAAAABKU0+s=")
.put(AdyenPaymentPluginApi.PROPERTY_MPI_DATA_ECI, "7")
.put(AdyenPaymentPluginApi.PROPERTY_CC_NUMBER, CC_3DS_NUMBER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you also passing a full PAN? Are you sure Adyen treats the request as an ApplePay one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you also passing a full PAN? Are you sure Adyen treats the request as an ApplePay one?

Yes, treats as applepay.

.put(AdyenPaymentPluginApi.PROPERTY_CC_EXPIRATION_MONTH, String.valueOf(CC_EXPIRATION_MONTH))
.put(AdyenPaymentPluginApi.PROPERTY_CC_EXPIRATION_YEAR, String.valueOf(CC_EXPIRATION_YEAR))
.put(AdyenPaymentPluginApi.PROPERTY_USER_AGENT, "Java/1.8")
.put(AdyenPaymentPluginApi.PROPERTY_ACCEPT_HEADER, "application/json")
.put(AdyenPaymentPluginApi.PROPERTY_TERM_URL, "dummy://url")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not needed.

.build());
private final Iterable<PluginProperty> propertiesWithAVSInfo = PluginProperties.buildPluginProperties(ImmutableMap.<String, String>builder()
.put(AdyenPaymentPluginApi.PROPERTY_CC_TYPE, CC_TYPE)
.put(AdyenPaymentPluginApi.PROPERTY_CC_LAST_NAME, "Avschecker")
Expand Down Expand Up @@ -425,6 +449,46 @@ public void testAuthorizeAndCheckAVSResult() throws Exception {
assertEquals(avsResult, "7 Both postal code and address match");
}

@Test(groups = "integration")
public void testAuthorizeWithGooglePay() throws Exception {
adyenPaymentPluginApi.addPaymentMethod(account.getId(), account.getPaymentMethodId(), adyenEmptyPaymentMethodPlugin(), true, propertiesWithGooglePay, context);
final Payment payment = TestUtils.buildPayment(account.getId(), account.getPaymentMethodId(), account.getCurrency(), killbillApi);

final PaymentTransaction authorizationTransaction = TestUtils.buildPaymentTransaction(payment, TransactionType.AUTHORIZE, new BigDecimal("25"), account.getCurrency());

final PaymentTransactionInfoPlugin authorizationInfoPlugin = adyenPaymentPluginApi.authorizePayment(account.getId(),
payment.getId(),
authorizationTransaction.getId(),
account.getPaymentMethodId(),
authorizationTransaction.getAmount(),
authorizationTransaction.getCurrency(),
propertiesWithGooglePay,
context);

assertNull(authorizationInfoPlugin.getGatewayErrorCode());
assertEquals(authorizationInfoPlugin.getStatus(), PaymentPluginStatus.PROCESSED);
}

@Test(groups = "integration")
public void testAuthorizeWithApplePay() throws Exception {
adyenPaymentPluginApi.addPaymentMethod(account.getId(), account.getPaymentMethodId(), adyenEmptyPaymentMethodPlugin(), true, propertiesWithApplePay, context);
final Payment payment = TestUtils.buildPayment(account.getId(), account.getPaymentMethodId(), account.getCurrency(), killbillApi);

final PaymentTransaction authorizationTransaction = TestUtils.buildPaymentTransaction(payment, TransactionType.AUTHORIZE, new BigDecimal("260"), account.getCurrency());

final PaymentTransactionInfoPlugin authorizationInfoPlugin = adyenPaymentPluginApi.authorizePayment(account.getId(),
payment.getId(),
authorizationTransaction.getId(),
account.getPaymentMethodId(),
authorizationTransaction.getAmount(),
authorizationTransaction.getCurrency(),
propertiesWithApplePay,
context);

assertNull(authorizationInfoPlugin.getGatewayErrorCode());
assertEquals(authorizationInfoPlugin.getStatus(), PaymentPluginStatus.PROCESSED);
}

@Test(groups = "integration")
public void testAuthorizeAndCheckBadAVSResult() throws Exception {
adyenPaymentPluginApi.addPaymentMethod(account.getId(), account.getPaymentMethodId(), adyenEmptyPaymentMethodPlugin(), true, propertiesWithAVSInfo, context);
Expand Down