Skip to content

Commit

Permalink
2.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
adyen-git-manager committed Jan 15, 2019
1 parent 6f099be commit c21f4db
Show file tree
Hide file tree
Showing 24 changed files with 185 additions and 66 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ To give you as much flexibility as possible, our Android SDK can be integrated i
Import the quick integration modules by adding these lines to your build.gradle file.

```groovy
final checkoutVersion = "2.3.0"
final checkoutVersion = "2.3.1"
implementation "com.adyen.checkout:ui:${checkoutVersion}"
implementation "com.adyen.checkout:nfc:${checkoutVersion}" // Optional; Integrates NFC card reader in card UI
implementation "com.adyen.checkout:wechatpay:${checkoutVersion}" // Optional; Integrates support for WeChat Pay
Expand Down Expand Up @@ -136,7 +136,7 @@ By default, we use the font that is declared in the theme that is used for check
#### Installation
Import the following modules by adding these line to your `build.gradle` file.
```groovy
final checkoutVersion = "2.3.0"
final checkoutVersion = "2.3.1"
implementation "com.adyen.checkout:core:${checkoutVersion}"
implementation "com.adyen.checkout:core-card:${checkoutVersion}" // Optional; Required for processing card payments.
implementation "com.adyen.checkout:nfc:${checkoutVersion}" // Optional; Enables reading of card information with the device"s NFC chip.
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ ext {
"com.tencent.mm.opensdk:wechat-sdk-android-without-mta:9a15154c07c05eadba8351c110647c1754316e32d8f12f55e24679891b52739c:SHA-256",
]

versionCode = 206
versionName = "2.3.0"
versionCode = 207
versionName = "2.3.1"

testCoverageEnabled = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,39 +196,7 @@ public void setErrorHandler(@NonNull Activity activity, @NonNull ErrorHandler er
@Override
public void initiatePayment(@NonNull PaymentMethod paymentMethod, @Nullable PaymentMethodDetails paymentMethodDetails) {
PaymentSessionImpl paymentSession = mPaymentSessionEntity.paymentSession;
initiatePayment(paymentSession, (PaymentMethodImpl) paymentMethod, paymentMethodDetails);
}

private void initiatePayment(
@NonNull PaymentSessionImpl paymentSession,
@NonNull final PaymentMethodImpl paymentMethod,
@Nullable PaymentMethodDetails paymentMethodDetails
) {
String paymentData = paymentSession.getPaymentData();
String paymentMethodData = paymentMethod.getPaymentMethodData();
PaymentInitiation paymentInitiation = new PaymentInitiation.Builder(paymentData, paymentMethodData)
.setPaymentMethodDetails(paymentMethodDetails)
.build();

final Callable<PaymentInitiationResponse> callable = CheckoutApi
.getInstance(mApplication)
.initiatePayment(paymentSession, paymentInitiation);

mExecutorService.submit(new Runnable() {
@Override
public void run() {
handleRequestStarted();

try {
PaymentInitiationResponse response = callable.call();
handlePaymentInitiationResponse(paymentMethod, response);
} catch (Exception e) {
handleException(e, "An error occurred while initiating the payment.");
} finally {
handleRequestFinished();
}
}
});
initiatePaymentInternal(paymentSession, (PaymentMethodImpl) paymentMethod, paymentMethodDetails);
}

@Override
Expand Down Expand Up @@ -256,7 +224,7 @@ public void submitAdditionalDetails(@NonNull PaymentMethodDetails paymentMethodD
}
}

initiatePayment(paymentSession, paymentMethod, paymentMethodDetails);
initiatePaymentInternal(paymentSession, paymentMethod, paymentMethodDetails);
}

@Override
Expand All @@ -277,7 +245,7 @@ public void handleRedirectResult(@NonNull final Uri redirectResult) {

if (redirectFields.isSubmitPaymentMethodReturnData()) {
AppResponseDetails appResponseDetails = new AppResponseDetails.Builder(redirectResult.getQuery()).build();
initiatePayment(paymentSession, paymentMethod, appResponseDetails);
initiatePaymentInternal(paymentSession, paymentMethod, appResponseDetails);
} else {
try {
JSONObject jsonObject = new JSONObject();
Expand Down Expand Up @@ -342,6 +310,37 @@ public void run() {
});
}

private void initiatePaymentInternal(
@NonNull PaymentSessionImpl paymentSession,
@NonNull final PaymentMethodImpl paymentMethod,
@Nullable PaymentMethodDetails paymentMethodDetails
) {
String paymentData = paymentSession.getPaymentData();
String paymentMethodData = paymentMethod.getPaymentMethodData();
PaymentInitiation paymentInitiation = new PaymentInitiation.Builder(paymentData, paymentMethodData)
.setPaymentMethodDetails(paymentMethodDetails)
.build();

final Callable<PaymentInitiationResponse> callable = CheckoutApi
.getInstance(mApplication)
.initiatePayment(paymentSession, paymentInitiation);

handleRequestStarted();
mExecutorService.submit(new Runnable() {
@Override
public void run() {
try {
PaymentInitiationResponse response = callable.call();
handlePaymentInitiationResponse(paymentMethod, response);
} catch (Exception e) {
handleException(e, "An error occurred while initiating the payment.");
} finally {
handleRequestFinished();
}
}
});
}

private void handleRequestStarted() {
mNetworkingStateImpl.onRequestStarted();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public JSONObject serialize() throws JSONException {
deviceInfo.put("deviceModel", DEVICE_MODEL);
deviceInfo.put("deviceIdentifier", mDeviceIdentifier);
deviceInfo.put("integration", mIntegration);
deviceInfo.put("locale", mLocale);
deviceInfo.put("locale", getLocaleWithoutScript(mLocale));
deviceInfo.put("generationTime", mGenerationTime);

return deviceInfo;
Expand Down Expand Up @@ -124,4 +124,13 @@ public int hashCode() {
result = HashUtils.MULTIPLIER * result + (mGenerationTime != null ? mGenerationTime.hashCode() : 0);
return result;
}

/**
* Some locales have extra part named "Language Script" that specified by # after Region code e.g. "zh_CN_#Hans"
* Since backend doesn't support "script" part of locale, we need to remove it!
* This function parse locale and return string with `${LanguageCode}_${RegionCode}` format.
*/
private String getLocaleWithoutScript(@NonNull Locale locale) {
return String.format("%s_%s", locale.getLanguage(), locale.getCountry());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public AmountImpl getAmount() {
return mAmount;
}

@NonNull
@Override
public String getCountryCode() {
return mCountryCode;
}

@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
Expand Down Expand Up @@ -107,11 +113,6 @@ public String toString() {
return "Payment{" + "CountryCode='" + mCountryCode + '\'' + ", Amount=" + mAmount + '}';
}

@NonNull
public String getCountryCode() {
return mCountryCode;
}

@NonNull
public String getReference() {
return mReference;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ public interface Payment extends Parcelable {
*/
@NonNull
Amount getAmount();

/**
* @return The code of the country specified for this Payment.
*/
@NonNull
String getCountryCode();
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static com.adyen.checkout.core.model.OpenInvoiceDetails.KEY_PERSONAL_DETAILS;
import static com.adyen.checkout.core.model.OpenInvoiceDetails.KEY_SEPARATE_DELIVERY_ADDRESS;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
Expand All @@ -37,13 +38,13 @@
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.adyen.checkout.core.CheckoutException;
import com.adyen.checkout.core.Observer;
import com.adyen.checkout.core.PaymentReference;
import com.adyen.checkout.core.SearchHandler;
import com.adyen.checkout.core.internal.model.InputDetailImpl;
import com.adyen.checkout.core.internal.model.PaymentImpl;
import com.adyen.checkout.core.model.Address;
import com.adyen.checkout.core.model.FieldSetConfiguration;
import com.adyen.checkout.core.model.InputDetail;
Expand Down Expand Up @@ -71,6 +72,10 @@ public class OpenInvoiceDetailsActivity extends CheckoutDetailsActivity implemen
private static final String KLARNA_CONSENT_URL = "https://cdn.klarna.com/1.0/shared/content/legal/terms/2/de_de/consent";
private static final String KLARNA_MORE_INFO_URL = "https://cdn.klarna.com/1.0/shared/content/legal/terms/2/%s/invoice";

private static final String AFTERPAY_NL_CONSENT_URL = "https://www.afterpay.nl/nl/algemeen/betalen-met-afterpay/betalingsvoorwaarden";
private static final String AFTERPAY_BE_CONSENT_URL = "https://www.afterpay.be/be/footer/betalen-met-afterpay/betalingsvoorwaarden";
private static final String AFTERPAY_US_CONSENT_URL = "https://www.afterpay.nl/en/algemeen/pay-with-afterpay/payment-conditions";

private PaymentMethod mPaymentMethod;
private SearchHandler<KlarnaSsnLookupResponse> mSearchHandler;

Expand Down Expand Up @@ -173,6 +178,14 @@ public void onClick(View v) {
});
}

private boolean isKlarna() {
return PaymentMethodTypes.KLARNA.equals(mPaymentMethod.getType());
}

private boolean isAfterpay() {
return PaymentMethodTypes.AFTERPAY.equals(mPaymentMethod.getType());
}

private void setupSSnLookup() {
if (mPersonalDetailsLayout.getFormVisibility() == FieldSetConfiguration.FieldVisibility.READ_ONLY) {
return;
Expand Down Expand Up @@ -221,7 +234,7 @@ public void onSsnInputFinished(@NonNull String ssnNumber) {
mSsnLookupEditText.addTextChangedListener(new AsYouTypeSsnFormatter(ssnCompleteCallback));
mSsnLookupEditText.addTextChangedListener(new SimpleTextWatcher() {
@Override
public void afterTextChanged(Editable s) {
public void afterTextChanged(@NonNull Editable s) {
checkValidation();
}
});
Expand Down Expand Up @@ -305,7 +318,7 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
break;
case KEY_CONSENT_CHECKBOX:
setupKlarnaConsent();
setupConsent();
break;
default:
if (!detail.isOptional()) {
Expand All @@ -317,50 +330,99 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
}

private void setupKlarnaConsent() {
mConsentLayout.setVisibility(View.VISIBLE);
private void setupConsent() {
String highlighted;
String termsAndConditions;

if (isKlarna()) {
highlighted = getString(R.string.checkout_klarna_consent);
termsAndConditions = getString(R.string.checkout_klarna_terms_and_conditions_text);
} else if (isAfterpay()) {
highlighted = getString(R.string.checkout_afterpay_conditions);
termsAndConditions = getString(R.string.checkout_afterpay_terms_and_conditions_text);
} else {
return;
}

String consent = getString(R.string.checkout_klarna_consent);
String termsAndConditions = getString(R.string.checkout_klarna_terms_and_conditions_text);
final int replacePosition = termsAndConditions.indexOf("%s");

mConsentLayout.setVisibility(View.VISIBLE);

if (replacePosition > -1) {
final int endOfSpan = replacePosition + consent.length();
SpannableStringBuilder spannableTermsAndConditions = new SpannableStringBuilder(String.format(termsAndConditions, consent));
final int endOfSpan = replacePosition + highlighted.length();
SpannableStringBuilder spannableTermsAndConditions = new SpannableStringBuilder(String.format(termsAndConditions, highlighted));
spannableTermsAndConditions.setSpan(new UnderlineSpan(), replacePosition, endOfSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableTermsAndConditions.setSpan(new StyleSpan(Typeface.BOLD), replacePosition, endOfSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mConsentText.setText(spannableTermsAndConditions);
} else {
mConsentText.setText(String.format(termsAndConditions, consent));
mConsentText.setText(String.format(termsAndConditions, highlighted));
}

if (isKlarna()) {
klarnaConsentClick();
} else if (isAfterpay()) {
afterpayConsentClick();
}

mConsentSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checkValidation();
}
});
}

private void klarnaConsentClick() {
mConsentText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(KLARNA_CONSENT_URL));
startActivity(browserIntent);
launchBrowser(Uri.parse(KLARNA_CONSENT_URL));
}
});
}

mConsentSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
private void afterpayConsentClick() {
getPaymentHandler().getPaymentSessionObservable().observe(this, new Observer<PaymentSession>() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checkValidation();
public void onChanged(@NonNull PaymentSession paymentSession) {

String countryCode = paymentSession.getPayment().getCountryCode().toLowerCase(Locale.ROOT);
Locale userLocale = LocaleUtil.getLocale(OpenInvoiceDetailsActivity.this);

boolean isSameLocaleAndCountry = countryCode.toUpperCase(Locale.ROOT).equals(userLocale.getCountry().toUpperCase(Locale.ROOT));

final String url;
if (isSameLocaleAndCountry && "NL".equals(countryCode.toUpperCase(Locale.ROOT))) {
url = AFTERPAY_NL_CONSENT_URL;
} else if (isSameLocaleAndCountry && "BE".equals(countryCode.toUpperCase(Locale.ROOT))) {
url = AFTERPAY_BE_CONSENT_URL;
} else {
url = AFTERPAY_US_CONSENT_URL;
}

mConsentText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
launchBrowser(Uri.parse(url));
}
});
}
});


}

private void setupMoreInformationButton() {
//this button only applies for Klarna payment method
if (PaymentMethodTypes.KLARNA.equals(mPaymentMethod.getType())) {
if (isKlarna()) {
final Button moreInformationButton = findViewById(R.id.button_more_information);
moreInformationButton.setVisibility(View.VISIBLE);

getPaymentHandler().getPaymentSessionObservable().observe(this, new Observer<PaymentSession>() {
@Override
public void onChanged(@NonNull PaymentSession paymentSession) {
//the binding legal page is based on the country of origin
String countryCode = ((PaymentImpl) paymentSession.getPayment()).getCountryCode().toLowerCase(Locale.ROOT);
String countryCode = paymentSession.getPayment().getCountryCode().toLowerCase(Locale.ROOT);
Locale userLocale = LocaleUtil.getLocale(OpenInvoiceDetailsActivity.this);
//but we can show an english version if the shopper locale is not the same
String klarnaCountryCode;
Expand All @@ -375,15 +437,22 @@ public void onChanged(@NonNull PaymentSession paymentSession) {
moreInformationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(klarnaUrl));
startActivity(browserIntent);
launchBrowser(Uri.parse(klarnaUrl));
}
});
}
});
}
}

private void launchBrowser(@NonNull Uri uri) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, uri));
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), R.string.checkout_error_redirect_failed, Toast.LENGTH_LONG).show();
}
}

private boolean areAllDetailsValid() {

boolean isValid = mPersonalDetailsLayout.isValid() && mBillingAddressDetailsLayout.isValid();
Expand Down
Loading

0 comments on commit c21f4db

Please sign in to comment.