Skip to content
This repository was archived by the owner on Jan 3, 2024. It is now read-only.

Commit d3a31a0

Browse files
ngoryachevisnifer
authored andcommitted
[5.0.0] Big Breaking Android Refactoring
1 parent 36a3c1f commit d3a31a0

18 files changed

+1271
-722
lines changed

android/build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ dependencies {
2727
compile 'com.facebook.react:react-native:+'
2828
compile 'com.android.support:support-v4:26.1.0'
2929
compile 'com.android.support:appcompat-v7:26.1.0'
30-
compile 'com.google.android.gms:play-services-wallet:10.+'
30+
compile 'com.google.android.gms:play-services-wallet:11.8.0'
31+
compile 'com.google.firebase:firebase-core:11.8.0'
3132
compile 'com.stripe:stripe-android:6.0.0'
3233
compile 'com.github.tipsi:CreditCardEntry:1.4.8.10'
3334
}

android/src/main/java/com/gettipsi/stripe/CustomCardInputReactManager.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
145145
try {
146146
currentMonth = view.getCreditCard().getExpMonth();
147147
}catch (Exception e){
148-
if(charSequence.length() == 0)
148+
if (charSequence.length() == 0)
149149
currentMonth = 0;
150150
}
151151
try {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
package com.gettipsi.stripe;
2+
3+
import android.app.Activity;
4+
import android.content.Intent;
5+
import android.support.annotation.NonNull;
6+
7+
import com.facebook.react.bridge.Promise;
8+
import com.facebook.react.bridge.ReadableMap;
9+
import com.gettipsi.stripe.util.ArgCheck;
10+
import com.gettipsi.stripe.util.Converters;
11+
import com.gettipsi.stripe.util.Fun0;
12+
import com.google.android.gms.common.api.ApiException;
13+
import com.google.android.gms.common.api.Status;
14+
import com.google.android.gms.tasks.OnCompleteListener;
15+
import com.google.android.gms.tasks.Task;
16+
import com.google.android.gms.wallet.AutoResolveHelper;
17+
import com.google.android.gms.wallet.CardRequirements;
18+
import com.google.android.gms.wallet.IsReadyToPayRequest;
19+
import com.google.android.gms.wallet.PaymentData;
20+
import com.google.android.gms.wallet.PaymentDataRequest;
21+
import com.google.android.gms.wallet.PaymentMethodTokenizationParameters;
22+
import com.google.android.gms.wallet.PaymentsClient;
23+
import com.google.android.gms.wallet.ShippingAddressRequirements;
24+
import com.google.android.gms.wallet.TransactionInfo;
25+
import com.google.android.gms.wallet.Wallet;
26+
import com.google.android.gms.wallet.WalletConstants;
27+
import com.stripe.android.BuildConfig;
28+
import com.stripe.android.model.Token;
29+
30+
import java.util.Arrays;
31+
import java.util.Collection;
32+
33+
import static com.gettipsi.stripe.util.Converters.convertTokenToWritableMap;
34+
import static com.gettipsi.stripe.util.Converters.getAllowedShippingCountryCodes;
35+
import static com.gettipsi.stripe.util.Converters.getBillingAddress;
36+
import static com.gettipsi.stripe.util.Converters.putExtraToTokenMap;
37+
import static com.gettipsi.stripe.util.PayParams.BILLING_ADDRESS_REQUIRED;
38+
import static com.gettipsi.stripe.util.PayParams.CURRENCY_CODE;
39+
import static com.gettipsi.stripe.util.PayParams.SHIPPING_ADDRESS_REQUIRED;
40+
import static com.gettipsi.stripe.util.PayParams.TOTAL_PRICE;
41+
42+
/**
43+
* Created by ngoriachev on 13/03/2018.
44+
* see https://developers.google.com/pay/api/tutorial
45+
*/
46+
public final class GoogleApiPayFlowImpl extends PayFlow {
47+
48+
private static final String TAG = GoogleApiPayFlowImpl.class.getSimpleName();
49+
private static final int LOAD_PAYMENT_DATA_REQUEST_CODE = 100500;
50+
51+
private PaymentsClient mPaymentsClient;
52+
private Promise payPromise;
53+
54+
public GoogleApiPayFlowImpl(@NonNull Fun0<Activity> activityProvider) {
55+
super(activityProvider);
56+
}
57+
58+
private PaymentsClient createPaymentsClient(@NonNull Activity activity) {
59+
return Wallet.getPaymentsClient(
60+
activity,
61+
new Wallet.WalletOptions.Builder().setEnvironment(getEnvironment()).build());
62+
}
63+
64+
private void isReadyToPay(@NonNull Activity activity, @NonNull final Promise promise) {
65+
ArgCheck.nonNull(activity);
66+
ArgCheck.nonNull(promise);
67+
68+
IsReadyToPayRequest request =
69+
IsReadyToPayRequest.newBuilder()
70+
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
71+
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
72+
.build();
73+
mPaymentsClient = createPaymentsClient(activity);
74+
Task<Boolean> task = mPaymentsClient.isReadyToPay(request);
75+
task.addOnCompleteListener(
76+
new OnCompleteListener<Boolean>() {
77+
public void onComplete(Task<Boolean> task) {
78+
try {
79+
boolean result = task.getResult(ApiException.class);
80+
promise.resolve(result);
81+
} catch (ApiException exception) {
82+
promise.reject(TAG, String.format("Error, statusCode: %d", exception.getStatusCode()));
83+
}
84+
}
85+
});
86+
}
87+
88+
private PaymentMethodTokenizationParameters createPaymentMethodTokenizationParameters() {
89+
return PaymentMethodTokenizationParameters.newBuilder()
90+
.setPaymentMethodTokenizationType(WalletConstants.PAYMENT_METHOD_TOKENIZATION_TYPE_PAYMENT_GATEWAY)
91+
.addParameter("gateway", "stripe")
92+
.addParameter("stripe:publishableKey", getPublishableKey())
93+
.addParameter("stripe:version", BuildConfig.VERSION_NAME)
94+
.build();
95+
}
96+
97+
private PaymentDataRequest createPaymentDataRequest(ReadableMap payParams) {
98+
final String estimatedTotalPrice = payParams.getString(TOTAL_PRICE);
99+
final String currencyCode = payParams.getString(CURRENCY_CODE);
100+
final boolean billingAddressRequired = Converters.getValue(payParams, BILLING_ADDRESS_REQUIRED, false);
101+
final Boolean shippingAddressRequired = Converters.getValue(payParams, SHIPPING_ADDRESS_REQUIRED, false);
102+
final Collection<String> allowedCountryCodes = getAllowedShippingCountryCodes(payParams);
103+
104+
return createPaymentDataRequest(estimatedTotalPrice, currencyCode, billingAddressRequired, shippingAddressRequired, allowedCountryCodes);
105+
}
106+
107+
private PaymentDataRequest createPaymentDataRequest(@NonNull final String totalPrice,
108+
@NonNull final String currencyCode,
109+
final boolean billingAddressRequired,
110+
final boolean shippingAddressRequired,
111+
@NonNull final Collection<String> countryCodes
112+
) {
113+
114+
ArgCheck.isDouble(totalPrice);
115+
ArgCheck.notEmptyString(currencyCode);
116+
117+
PaymentDataRequest.Builder builder = PaymentDataRequest.newBuilder();
118+
builder.setTransactionInfo(
119+
TransactionInfo.newBuilder()
120+
.setTotalPriceStatus(WalletConstants.TOTAL_PRICE_STATUS_ESTIMATED)
121+
.setTotalPrice(totalPrice)
122+
.setCurrencyCode(currencyCode)
123+
.build());
124+
125+
builder
126+
.setCardRequirements(
127+
CardRequirements.newBuilder()
128+
.addAllowedCardNetworks(
129+
Arrays.asList(
130+
WalletConstants.CARD_NETWORK_AMEX,
131+
WalletConstants.CARD_NETWORK_DISCOVER,
132+
WalletConstants.CARD_NETWORK_VISA,
133+
WalletConstants.CARD_NETWORK_MASTERCARD))
134+
.setBillingAddressRequired(billingAddressRequired)
135+
.build())
136+
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_CARD)
137+
.addAllowedPaymentMethod(WalletConstants.PAYMENT_METHOD_TOKENIZED_CARD)
138+
.setShippingAddressRequired(shippingAddressRequired);
139+
140+
if (countryCodes.size() > 0) {
141+
builder.setShippingAddressRequirements(
142+
ShippingAddressRequirements.newBuilder()
143+
.addAllowedCountryCodes(countryCodes)
144+
.build());
145+
}
146+
147+
builder.setPaymentMethodTokenizationParameters(createPaymentMethodTokenizationParameters());
148+
return builder.build();
149+
}
150+
151+
private void startPaymentRequest(@NonNull Activity activity, @NonNull PaymentDataRequest request) {
152+
ArgCheck.nonNull(activity);
153+
ArgCheck.nonNull(request);
154+
155+
mPaymentsClient = createPaymentsClient(activity);
156+
157+
AutoResolveHelper.resolveTask(
158+
mPaymentsClient.loadPaymentData(request),
159+
activity,
160+
LOAD_PAYMENT_DATA_REQUEST_CODE);
161+
}
162+
163+
@Override
164+
public void paymentRequestWithAndroidPay(@NonNull ReadableMap payParams, @NonNull Promise promise) {
165+
ArgCheck.nonNull(payParams);
166+
ArgCheck.nonNull(promise);
167+
168+
Activity activity = activityProvider.call();
169+
if (activity == null) {
170+
promise.reject(TAG, NO_CURRENT_ACTIVITY_MSG);
171+
return;
172+
}
173+
174+
this.payPromise = promise;
175+
startPaymentRequest(activity, createPaymentDataRequest(payParams));
176+
}
177+
178+
@Override
179+
public void deviceSupportsAndroidPay(@NonNull Promise promise) {
180+
Activity activity = activityProvider.call();
181+
if (activity == null) {
182+
promise.reject(TAG, NO_CURRENT_ACTIVITY_MSG);
183+
return;
184+
}
185+
186+
if (!isPlayServicesAvailable(activity)) {
187+
promise.reject(TAG, PLAY_SERVICES_ARE_NOT_AVAILABLE_MSG);
188+
return;
189+
}
190+
191+
isReadyToPay(activity, promise);
192+
}
193+
194+
public boolean onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
195+
if (payPromise == null) {
196+
return false;
197+
}
198+
199+
switch (requestCode) {
200+
case LOAD_PAYMENT_DATA_REQUEST_CODE:
201+
switch (resultCode) {
202+
case Activity.RESULT_OK:
203+
PaymentData paymentData = PaymentData.getFromIntent(data);
204+
ArgCheck.nonNull(paymentData);
205+
String tokenJson = paymentData.getPaymentMethodToken().getToken();
206+
Token token = Token.fromString(tokenJson);
207+
if (token == null) {
208+
payPromise.reject(TAG, JSON_PARSING_ERROR_MSG);
209+
} else {
210+
payPromise.resolve(putExtraToTokenMap(
211+
convertTokenToWritableMap(token),
212+
getBillingAddress(paymentData),
213+
paymentData.getShippingAddress()));
214+
}
215+
break;
216+
case Activity.RESULT_CANCELED:
217+
payPromise.reject(TAG, PURCHASE_CANCELLED_MSG);
218+
break;
219+
case AutoResolveHelper.RESULT_ERROR:
220+
Status status = AutoResolveHelper.getStatusFromIntent(data);
221+
// Log the status for debugging.
222+
// Generally, there is no need to show an error to
223+
// the user as the Google Pay API will do that.
224+
payPromise.reject(TAG, status.getStatusMessage());
225+
break;
226+
227+
default:
228+
// Do nothing.
229+
}
230+
payPromise = null;
231+
return true;
232+
}
233+
234+
return false;
235+
}
236+
237+
}

0 commit comments

Comments
 (0)