1 | //
|
2 | // TPSStripeManager.m
|
3 | // TPSStripe
|
4 | //
|
5 | // Created by Anton Petrov on 28.10.16.
|
6 | // Copyright © 2016 Tipsi. All rights reserved.
|
7 | //
|
8 |
|
9 | #import <EXPaymentsStripe/EXTPSStripeManager.h>
|
10 | #import <EXPaymentsStripe/EXTPSError.h>
|
11 |
|
12 | NSString * const kErrorKeyCode = @"errorCode";
|
13 | NSString * const kErrorKeyDescription = @"description";
|
14 | NSString * const kErrorKeyBusy = @"busy";
|
15 | NSString * const kErrorKeyApi = @"api";
|
16 | NSString * const kErrorKeyRedirectSpecific = @"redirectSpecific";
|
17 | NSString * const kErrorKeyCancelled = @"cancelled";
|
18 | NSString * const kErrorKeySourceStatusCanceled = @"sourceStatusCanceled";
|
19 | NSString * const kErrorKeySourceStatusPending = @"sourceStatusPending";
|
20 | NSString * const kErrorKeySourceStatusFailed = @"sourceStatusFailed";
|
21 | NSString * const kErrorKeySourceStatusUnknown = @"sourceStatusUnknown";
|
22 | NSString * const kErrorKeyDeviceNotSupportsNativePay = @"deviceNotSupportsNativePay";
|
23 | NSString * const kErrorKeyNoPaymentRequest = @"noPaymentRequest";
|
24 | NSString * const kErrorKeyNoMerchantIdentifier = @"noMerchantIdentifier";
|
25 | NSString * const kErrorKeyNoAmount = @"noAmount";
|
26 |
|
27 | @interface EXTPSStripeManager ()
|
28 |
|
29 | @property (nonatomic, weak) UMModuleRegistry *moduleRegistry;
|
30 |
|
31 | @end
|
32 |
|
33 | NSString * const TPSPaymentNetworkAmex = @"american_express";
|
34 | NSString * const TPSPaymentNetworkDiscover = @"discover";
|
35 | NSString * const TPSPaymentNetworkMasterCard = @"master_card";
|
36 | NSString * const TPSPaymentNetworkVisa = @"visa";
|
37 |
|
38 | @implementation EXTPSStripeManager
|
39 | {
|
40 | NSString *publishableKey;
|
41 | NSString *merchantId;
|
42 | NSDictionary *errorCodes;
|
43 |
|
44 | UMPromiseResolveBlock promiseResolver;
|
45 | UMPromiseRejectBlock promiseRejector;
|
46 |
|
47 | BOOL requestIsCompleted;
|
48 |
|
49 | void (^applePayCompletion)(PKPaymentAuthorizationStatus);
|
50 | NSError *applePayStripeError;
|
51 | }
|
52 |
|
53 | - (instancetype)init {
|
54 | if ((self = [super init])) {
|
55 | requestIsCompleted = YES;
|
56 | }
|
57 | return self;
|
58 | }
|
59 |
|
60 | - (dispatch_queue_t)methodQueue {
|
61 | return dispatch_get_main_queue();
|
62 | }
|
63 |
|
64 | - (NSDictionary *)constantsToExport
|
65 | {
|
66 | return @{
|
67 | @"TPSErrorDomain": TPSErrorDomain,
|
68 | @"TPSErrorCodeApplePayNotConfigured": [@(TPSErrorCodeApplePayNotConfigured) stringValue],
|
69 | @"TPSErrorCodePreviousRequestNotCompleted": [@(TPSErrorCodePreviousRequestNotCompleted) stringValue],
|
70 | @"TPSErrorCodeUserCancel": [@(TPSErrorCodeUserCancel) stringValue],
|
71 | };
|
72 | }
|
73 |
|
74 | UM_REGISTER_MODULE();
|
75 |
|
76 | + (const NSString *)exportedModuleName
|
77 | {
|
78 | return @"StripeModule";
|
79 | }
|
80 |
|
81 | UM_EXPORT_METHOD_AS(init, init:(NSDictionary *)options
|
82 | errorCodes:(NSDictionary *)errors
|
83 | resolver:(UMPromiseResolveBlock)resolve
|
84 | rejecter:(UMPromiseRejectBlock)reject) {
|
85 | publishableKey = options[@"publishableKey"];
|
86 | merchantId = options[@"merchantId"];
|
87 | errorCodes = errors;
|
88 | [Stripe setDefaultPublishableKey:publishableKey];
|
89 | resolve(@(YES));
|
90 | }
|
91 |
|
92 | UM_EXPORT_METHOD_AS(deviceSupportsApplePay, deviceSupportsApplePay:(UMPromiseResolveBlock)resolve
|
93 | rejecter:(UMPromiseRejectBlock)reject) {
|
94 | resolve(@([PKPaymentAuthorizationViewController canMakePayments]));
|
95 | }
|
96 |
|
97 | UM_EXPORT_METHOD_AS(canMakeApplePayPayments, canMakeApplePayPayments:(NSDictionary *)options
|
98 | resolver:(UMPromiseResolveBlock)resolve
|
99 | rejecter:(UMPromiseRejectBlock)reject) {
|
100 | NSArray <NSString *> *paymentNetworksStrings =
|
101 | options[@"networks"] ?: [EXTPSStripeManager supportedPaymentNetworksStrings];
|
102 |
|
103 | NSArray <PKPaymentNetwork> *networks = [self paymentNetworks:paymentNetworksStrings];
|
104 | resolve(@([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:networks]));
|
105 | }
|
106 |
|
107 | UM_EXPORT_METHOD_AS(completeApplePayRequest, completeApplePayRequest:(UMPromiseResolveBlock)resolve
|
108 | rejecter:(UMPromiseRejectBlock)reject) {
|
109 | if (applePayCompletion) {
|
110 | promiseResolver = resolve;
|
111 | [self resolveApplePayCompletion:PKPaymentAuthorizationStatusSuccess];
|
112 | } else {
|
113 | resolve(nil);
|
114 | }
|
115 | }
|
116 |
|
117 | UM_EXPORT_METHOD_AS(cancelApplePayRequest, cancelApplePayRequest:(UMPromiseResolveBlock)resolve
|
118 | rejecter:(UMPromiseRejectBlock)reject) {
|
119 | if (applePayCompletion) {
|
120 | promiseResolver = resolve;
|
121 | [self resolveApplePayCompletion:PKPaymentAuthorizationStatusFailure];
|
122 | } else {
|
123 | resolve(nil);
|
124 | }
|
125 | }
|
126 |
|
127 | UM_EXPORT_METHOD_AS(createTokenWithCard, createTokenWithCard:(NSDictionary *)params
|
128 | resolver:(UMPromiseResolveBlock)resolve
|
129 | rejecter:(UMPromiseRejectBlock)reject) {
|
130 | if(!requestIsCompleted) {
|
131 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyBusy];
|
132 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
133 | return;
|
134 | }
|
135 |
|
136 | requestIsCompleted = NO;
|
137 |
|
138 | STPCardParams *cardParams = [[STPCardParams alloc] init];
|
139 |
|
140 | [cardParams setNumber: params[@"number"]];
|
141 | [cardParams setExpMonth: [params[@"expMonth"] integerValue]];
|
142 | [cardParams setExpYear: [params[@"expYear"] integerValue]];
|
143 | [cardParams setCvc: params[@"cvc"]];
|
144 |
|
145 | [cardParams setCurrency: params[@"currency"]];
|
146 | [cardParams setName: params[@"name"]];
|
147 | [cardParams setAddressLine1: params[@"addressLine1"]];
|
148 | [cardParams setAddressLine2: params[@"addressLine2"]];
|
149 | [cardParams setAddressCity: params[@"addressCity"]];
|
150 | [cardParams setAddressState: params[@"addressState"]];
|
151 | [cardParams setAddressCountry: params[@"addressCountry"]];
|
152 | [cardParams setAddressZip: params[@"addressZip"]];
|
153 |
|
154 | STPAPIClient *stripeAPIClient = [self newAPIClient];
|
155 |
|
156 | [stripeAPIClient createTokenWithCard:cardParams completion:^(STPToken *token, NSError *error) {
|
157 | requestIsCompleted = YES;
|
158 |
|
159 | if (error) {
|
160 | NSDictionary *jsError = [errorCodes valueForKey:kErrorKeyApi];
|
161 | [self rejectPromiseWithCode:jsError[kErrorKeyCode] message:error.localizedDescription];
|
162 | } else {
|
163 | resolve([self convertTokenObject:token]);
|
164 | }
|
165 | }];
|
166 | }
|
167 |
|
168 | UM_EXPORT_METHOD_AS(createTokenWithBankAccount, createTokenWithBankAccount:(NSDictionary *)params
|
169 | resolver:(UMPromiseResolveBlock)resolve
|
170 | rejecter:(UMPromiseRejectBlock)reject) {
|
171 | if(!requestIsCompleted) {
|
172 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyBusy];
|
173 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
174 | return;
|
175 | }
|
176 |
|
177 | requestIsCompleted = NO;
|
178 |
|
179 | STPBankAccountParams *bankAccount = [[STPBankAccountParams alloc] init];
|
180 |
|
181 | [bankAccount setAccountNumber: params[@"accountNumber"]];
|
182 | [bankAccount setCountry: params[@"countryCode"]];
|
183 | [bankAccount setCurrency: params[@"currency"]];
|
184 | [bankAccount setRoutingNumber: params[@"routingNumber"]];
|
185 | [bankAccount setAccountHolderName: params[@"accountHolderName"]];
|
186 | STPBankAccountHolderType accountHolderType =
|
187 | [EXTPSConvert holderType:params[@"accountHolderType"]];
|
188 | [bankAccount setAccountHolderType: accountHolderType];
|
189 |
|
190 | STPAPIClient *stripeAPIClient = [self newAPIClient];
|
191 |
|
192 | [stripeAPIClient createTokenWithBankAccount:bankAccount completion:^(STPToken *token, NSError *error) {
|
193 | requestIsCompleted = YES;
|
194 |
|
195 | if (error) {
|
196 | NSDictionary *jsError = [errorCodes valueForKey:kErrorKeyApi];
|
197 | [self rejectPromiseWithCode:jsError[kErrorKeyCode] message:error.localizedDescription];
|
198 | } else {
|
199 | resolve([self convertTokenObject:token]);
|
200 | }
|
201 | }];
|
202 | }
|
203 |
|
204 | UM_EXPORT_METHOD_AS(createSourceWithParams, createSourceWithParams:(NSDictionary *)params
|
205 | resolver:(UMPromiseResolveBlock)resolve
|
206 | rejecter:(UMPromiseRejectBlock)reject) {
|
207 | if(!requestIsCompleted) {
|
208 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyBusy];
|
209 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
210 | return;
|
211 | }
|
212 |
|
213 | requestIsCompleted = NO;
|
214 |
|
215 | NSString *sourceType = params[@"type"];
|
216 | STPSourceParams *sourceParams;
|
217 | if ([sourceType isEqualToString:@"bancontact"]) {
|
218 | sourceParams = [STPSourceParams bancontactParamsWithAmount:[[params objectForKey:@"amount"] unsignedIntegerValue] name:params[@"name"] returnURL:params[@"returnURL"] statementDescriptor:params[@"statementDescriptor"]];
|
219 | }
|
220 | if ([sourceType isEqualToString:@"giropay"]) {
|
221 | sourceParams = [STPSourceParams giropayParamsWithAmount:[[params objectForKey:@"amount"] unsignedIntegerValue] name:params[@"name"] returnURL:params[@"returnURL"] statementDescriptor:params[@"statementDescriptor"]];
|
222 | }
|
223 | if ([sourceType isEqualToString:@"ideal"]) {
|
224 | sourceParams = [STPSourceParams idealParamsWithAmount:[[params objectForKey:@"amount"] unsignedIntegerValue] name:params[@"name"] returnURL:params[@"returnURL"] statementDescriptor:params[@"statementDescriptor"] bank:params[@"bank"]];
|
225 | }
|
226 | if ([sourceType isEqualToString:@"sepaDebit"]) {
|
227 | sourceParams = [STPSourceParams sepaDebitParamsWithName:params[@"name"] iban:params[@"iban"] addressLine1:params[@"addressLine1"] city:params[@"city"] postalCode:params[@"postalCode"] country:params[@"country"]];
|
228 | }
|
229 | if ([sourceType isEqualToString:@"sofort"]) {
|
230 | sourceParams = [STPSourceParams sofortParamsWithAmount:[[params objectForKey:@"amount"] unsignedIntegerValue] returnURL:params[@"returnURL"] country:params[@"country"] statementDescriptor:params[@"statementDescriptor"]];
|
231 | }
|
232 | if ([sourceType isEqualToString:@"threeDSecure"]) {
|
233 | sourceParams = [STPSourceParams threeDSecureParamsWithAmount:[[params objectForKey:@"amount"] unsignedIntegerValue] currency:params[@"currency"] returnURL:params[@"returnURL"] card:params[@"card"]];
|
234 | }
|
235 | if ([sourceType isEqualToString:@"alipay"]) {
|
236 | sourceParams = [STPSourceParams alipayParamsWithAmount:[[params objectForKey:@"amount"] unsignedIntegerValue] currency:params[@"currency"] returnURL:params[@"returnURL"]];
|
237 | }
|
238 |
|
239 | [[STPAPIClient sharedClient] createSourceWithParams:sourceParams completion:^(STPSource *source, NSError *error) {
|
240 | requestIsCompleted = YES;
|
241 |
|
242 | if (error) {
|
243 | reject(nil, nil, error);
|
244 | } else {
|
245 | if (source.redirect) {
|
246 | self.redirectContext = [[STPRedirectContext alloc] initWithSource:source completion:^(NSString *sourceID, NSString *clientSecret, NSError *error) {
|
247 | if (error) {
|
248 | NSDictionary *jsError = [errorCodes valueForKey:kErrorKeyRedirectSpecific];
|
249 | reject(jsError[kErrorKeyCode], error.localizedDescription, nil);
|
250 | } else {
|
251 | [[STPAPIClient sharedClient] startPollingSourceWithId:sourceID clientSecret:clientSecret timeout:10 completion:^(STPSource *source, NSError *error) {
|
252 | if (error) {
|
253 | NSDictionary *jsError = [errorCodes valueForKey:kErrorKeyApi];
|
254 | reject(jsError[kErrorKeyCode], error.localizedDescription, nil);
|
255 | } else {
|
256 | switch (source.status) {
|
257 | case STPSourceStatusChargeable:
|
258 | case STPSourceStatusConsumed:
|
259 | resolve([self convertSourceObject:source]);
|
260 | break;
|
261 | case STPSourceStatusCanceled: {
|
262 | NSDictionary *error = [errorCodes valueForKey:kErrorKeySourceStatusCanceled];
|
263 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
264 | }
|
265 | break;
|
266 | case STPSourceStatusPending: {
|
267 | NSDictionary *error = [errorCodes valueForKey:kErrorKeySourceStatusPending];
|
268 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
269 | }
|
270 | break;
|
271 | case STPSourceStatusFailed: {
|
272 | NSDictionary *error = [errorCodes valueForKey:kErrorKeySourceStatusFailed];
|
273 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
274 | }
|
275 | break;
|
276 | case STPSourceStatusUnknown: {
|
277 | NSDictionary *error = [errorCodes valueForKey:kErrorKeySourceStatusUnknown];
|
278 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
279 | }
|
280 | break;
|
281 | }
|
282 | }
|
283 | }];
|
284 | }
|
285 | }];
|
286 | [self.redirectContext startSafariAppRedirectFlow];
|
287 | } else {
|
288 | resolve([self convertSourceObject:source]);
|
289 | }
|
290 | }
|
291 | }];
|
292 | }
|
293 |
|
294 | UM_EXPORT_METHOD_AS(paymentRequestWithCardForm, paymentRequestWithCardForm:(NSDictionary *)options
|
295 | resolver:(UMPromiseResolveBlock)resolve
|
296 | rejecter:(UMPromiseRejectBlock)reject) {
|
297 | if(!requestIsCompleted) {
|
298 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyBusy];
|
299 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
300 | return;
|
301 | }
|
302 |
|
303 | requestIsCompleted = NO;
|
304 | // Save promise handlers to use in `paymentAuthorizationViewController`
|
305 | promiseResolver = resolve;
|
306 | promiseRejector = reject;
|
307 |
|
308 | NSUInteger requiredBillingAddressFields = [self billingType:options[@"requiredBillingAddressFields"]];
|
309 | NSString *companyName = options[@"companyName"] ? options[@"companyName"] : @"";
|
310 | STPUserInformation *prefilledInformation = [self userInformation:options[@"prefilledInformation"]];
|
311 | NSString *managedAccountCurrency = options[@"managedAccountCurrency"];
|
312 | NSString *nextPublishableKey = options[@"publishableKey"] ? options[@"publishableKey"] : publishableKey;
|
313 | UIModalPresentationStyle formPresentation = [self formPresentation:options[@"presentation"]];
|
314 | STPTheme *theme = [self formTheme:options[@"theme"]];
|
315 |
|
316 | STPPaymentConfiguration *configuration = [[STPPaymentConfiguration alloc] init];
|
317 | [configuration setRequiredBillingAddressFields:requiredBillingAddressFields];
|
318 | [configuration setCompanyName:companyName];
|
319 | [configuration setPublishableKey:nextPublishableKey];
|
320 |
|
321 | [configuration setCreateCardSources:[options[@"createCardSource"] boolValue]];
|
322 |
|
323 |
|
324 | STPAddCardViewController *addCardViewController = [[STPAddCardViewController alloc] initWithConfiguration:configuration theme:theme];
|
325 | [addCardViewController setDelegate:self];
|
326 | [addCardViewController setPrefilledInformation:prefilledInformation];
|
327 | [addCardViewController setManagedAccountCurrency:managedAccountCurrency];
|
328 | // STPAddCardViewController must be shown inside a UINavigationController.
|
329 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addCardViewController];
|
330 | [navigationController setModalPresentationStyle:formPresentation];
|
331 | navigationController.navigationBar.stp_theme = theme;
|
332 | [[self getViewController] presentViewController:navigationController animated:YES completion:nil];
|
333 | }
|
334 |
|
335 | UM_EXPORT_METHOD_AS(paymentRequestWithApplePay, paymentRequestWithApplePay:(NSArray *)items
|
336 | withOptions:(NSDictionary *)options
|
337 | resolver:(UMPromiseResolveBlock)resolve
|
338 | rejecter:(UMPromiseRejectBlock)reject) {
|
339 | if(!requestIsCompleted) {
|
340 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyBusy];
|
341 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
342 | return;
|
343 | }
|
344 |
|
345 | requestIsCompleted = NO;
|
346 | // Save promise handlers to use in `paymentAuthorizationViewController`
|
347 | promiseResolver = resolve;
|
348 | promiseRejector = reject;
|
349 |
|
350 | NSUInteger requiredShippingAddressFields = [self applePayAddressFields:options[@"requiredShippingAddressFields"]];
|
351 | NSUInteger requiredBillingAddressFields = [self applePayAddressFields:options[@"requiredBillingAddressFields"]];
|
352 | PKShippingType shippingType = [self applePayShippingType:options[@"shippingType"]];
|
353 | NSMutableArray *shippingMethodsItems = options[@"shippingMethods"] ? options[@"shippingMethods"] : [NSMutableArray array];
|
354 | NSString* currencyCode = options[@"currencyCode"] ? options[@"currencyCode"] : @"USD";
|
355 | NSString* countryCode = options[@"countryCode"] ? options[@"countryCode"] : @"US";
|
356 |
|
357 | NSMutableArray *shippingMethods = [NSMutableArray array];
|
358 |
|
359 | for (NSDictionary *item in shippingMethodsItems) {
|
360 | PKShippingMethod *shippingItem = [[PKShippingMethod alloc] init];
|
361 | shippingItem.label = item[@"label"];
|
362 | shippingItem.detail = item[@"detail"];
|
363 | shippingItem.amount = [NSDecimalNumber decimalNumberWithString:item[@"amount"]];
|
364 | shippingItem.identifier = item[@"id"];
|
365 | [shippingMethods addObject:shippingItem];
|
366 | }
|
367 |
|
368 | NSMutableArray *summaryItems = [NSMutableArray array];
|
369 |
|
370 | for (NSDictionary *item in items) {
|
371 | PKPaymentSummaryItem *summaryItem = [[PKPaymentSummaryItem alloc] init];
|
372 | summaryItem.label = item[@"label"];
|
373 | summaryItem.amount = [NSDecimalNumber decimalNumberWithString:item[@"amount"]];
|
374 | summaryItem.type = [@"pending" isEqualToString:item[@"type"]] ? PKPaymentSummaryItemTypePending : PKPaymentSummaryItemTypeFinal;
|
375 | [summaryItems addObject:summaryItem];
|
376 | }
|
377 |
|
378 | PKPaymentRequest *paymentRequest = [Stripe paymentRequestWithMerchantIdentifier:merchantId country:countryCode currency:currencyCode];
|
379 |
|
380 | [paymentRequest setRequiredShippingAddressFields:requiredShippingAddressFields];
|
381 | [paymentRequest setRequiredBillingAddressFields:requiredBillingAddressFields];
|
382 | [paymentRequest setPaymentSummaryItems:summaryItems];
|
383 | [paymentRequest setShippingMethods:shippingMethods];
|
384 | [paymentRequest setShippingType:shippingType];
|
385 |
|
386 | if ([self canSubmitPaymentRequest:paymentRequest rejecter:reject]) {
|
387 | PKPaymentAuthorizationViewController *paymentAuthorizationVC = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest];
|
388 | paymentAuthorizationVC.delegate = self;
|
389 | [[self getViewController] presentViewController:paymentAuthorizationVC animated:YES completion:nil];
|
390 | } else {
|
391 | // There is a problem with your Apple Pay configuration.
|
392 | [self resetPromiseCallbacks];
|
393 | requestIsCompleted = YES;
|
394 | }
|
395 | }
|
396 |
|
397 | UM_EXPORT_METHOD_AS(openApplePaySetup, openApplePaySetup:(UMPromiseResolveBlock)resolve
|
398 | rejecter:(UMPromiseRejectBlock)reject) {
|
399 | PKPassLibrary *library = [[PKPassLibrary alloc] init];
|
400 |
|
401 | // Here we should check, if openPaymentSetup selector exist
|
402 | if ([library respondsToSelector:NSSelectorFromString(@"openPaymentSetup")]) {
|
403 | [library openPaymentSetup];
|
404 | }
|
405 | }
|
406 |
|
407 | #pragma mark - Private
|
408 |
|
409 | -(UIViewController*) getViewController {
|
410 | return [[_moduleRegistry getModuleImplementingProtocol:@protocol(UMUtilitiesInterface)] currentViewController];
|
411 | }
|
412 |
|
413 | - (void)resolvePromise:(id)result {
|
414 | if (promiseResolver) {
|
415 | promiseResolver(result);
|
416 | }
|
417 | [self resetPromiseCallbacks];
|
418 | }
|
419 |
|
420 | - (void)rejectPromiseWithCode:(NSString *)code message:(NSString *)message {
|
421 | if (promiseRejector) {
|
422 | promiseRejector(code, message, nil);
|
423 | }
|
424 | [self resetPromiseCallbacks];
|
425 | }
|
426 |
|
427 | - (void)resetPromiseCallbacks {
|
428 | promiseResolver = nil;
|
429 | promiseRejector = nil;
|
430 | }
|
431 |
|
432 | - (void)resolveApplePayCompletion:(PKPaymentAuthorizationStatus)status {
|
433 | if (applePayCompletion) {
|
434 | applePayCompletion(status);
|
435 | }
|
436 | [self resetApplePayCallback];
|
437 | }
|
438 |
|
439 | - (void)resetApplePayCallback {
|
440 | applePayCompletion = nil;
|
441 | }
|
442 |
|
443 | - (BOOL)canSubmitPaymentRequest:(PKPaymentRequest *)paymentRequest rejecter:(UMPromiseRejectBlock)reject {
|
444 | if (![Stripe deviceSupportsApplePay]) {
|
445 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyDeviceNotSupportsNativePay];
|
446 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
447 | return NO;
|
448 | }
|
449 | if (paymentRequest == nil) {
|
450 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyNoPaymentRequest];
|
451 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
452 | return NO;
|
453 | }
|
454 | if (paymentRequest.merchantIdentifier == nil) {
|
455 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyNoMerchantIdentifier];
|
456 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
457 | return NO;
|
458 | }
|
459 | if ([[[paymentRequest.paymentSummaryItems lastObject] amount] floatValue] == 0) {
|
460 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyNoAmount];
|
461 | reject(error[kErrorKeyCode], error[kErrorKeyDescription], nil);
|
462 | return NO;
|
463 | }
|
464 | return YES;
|
465 | }
|
466 |
|
467 | #pragma mark - STPAddCardViewControllerDelegate
|
468 |
|
469 | - (void)addCardViewController:(STPAddCardViewController *)controller
|
470 | didCreateToken:(STPToken *)token
|
471 | completion:(STPErrorBlock)completion {
|
472 | [[self getViewController] dismissViewControllerAnimated:YES completion:nil];
|
473 |
|
474 | requestIsCompleted = YES;
|
475 | completion(nil);
|
476 | [self resolvePromise:[self convertTokenObject:token]];
|
477 | }
|
478 |
|
479 | - (void)addCardViewController:(STPAddCardViewController *)controller
|
480 | didCreateSource:(STPSource *)source
|
481 | completion:(STPErrorBlock)completion {
|
482 | [[self getViewController] dismissViewControllerAnimated:YES completion:nil];
|
483 |
|
484 | requestIsCompleted = YES;
|
485 | completion(nil);
|
486 | [self resolvePromise:[self convertSourceObject:source]];
|
487 | }
|
488 |
|
489 | - (void)addCardViewControllerDidCancel:(STPAddCardViewController *)addCardViewController {
|
490 | [[self getViewController] dismissViewControllerAnimated:YES completion:nil];
|
491 |
|
492 | if (!requestIsCompleted) {
|
493 | requestIsCompleted = YES;
|
494 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyCancelled];
|
495 | [self rejectPromiseWithCode:error[kErrorKeyCode] message:error[kErrorKeyDescription]];
|
496 | }
|
497 |
|
498 | }
|
499 |
|
500 | #pragma mark PKPaymentAuthorizationViewControllerDelegate
|
501 |
|
502 | - (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
|
503 | didAuthorizePayment:(PKPayment *)payment
|
504 | completion:(void (^)(PKPaymentAuthorizationStatus))completion {
|
505 | // Save for deffered call
|
506 | applePayCompletion = completion;
|
507 |
|
508 | STPAPIClient *stripeAPIClient = [self newAPIClient];
|
509 |
|
510 | [stripeAPIClient createTokenWithPayment:payment completion:^(STPToken * _Nullable token, NSError * _Nullable error) {
|
511 | requestIsCompleted = YES;
|
512 |
|
513 | if (error) {
|
514 | // Save for deffered use
|
515 | applePayStripeError = error;
|
516 | [self resolveApplePayCompletion:PKPaymentAuthorizationStatusFailure];
|
517 | } else {
|
518 | NSDictionary *result = [self convertTokenObject:token];
|
519 | NSDictionary *extra = @{
|
520 | @"billingContact": [self contactDetails:payment.billingContact] ?: [NSNull null],
|
521 | @"shippingContact": [self contactDetails:payment.shippingContact] ?: [NSNull null],
|
522 | @"shippingMethod": [self shippingDetails:payment.shippingMethod] ?: [NSNull null]
|
523 | };
|
524 |
|
525 | [result setValue:extra forKey:@"extra"];
|
526 |
|
527 | [self resolvePromise:result];
|
528 | }
|
529 | }];
|
530 | }
|
531 |
|
532 |
|
533 | - (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
|
534 | [self resetApplePayCallback];
|
535 |
|
536 | void(^completion)() = ^{
|
537 | if (!requestIsCompleted) {
|
538 | requestIsCompleted = YES;
|
539 |
|
540 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyCancelled];
|
541 | [self rejectPromiseWithCode:error[kErrorKeyCode] message:error[kErrorKeyDescription]];
|
542 | } else {
|
543 | if (applePayStripeError) {
|
544 | NSDictionary *error = [errorCodes valueForKey:kErrorKeyApi];
|
545 | [self rejectPromiseWithCode:error[kErrorKeyCode] message:applePayStripeError.localizedDescription];
|
546 | applePayStripeError = nil;
|
547 | } else {
|
548 | [self resolvePromise:nil];
|
549 | }
|
550 | }
|
551 | };
|
552 |
|
553 | [[self getViewController] dismissViewControllerAnimated:YES completion:completion];
|
554 | }
|
555 |
|
556 | - (STPAPIClient *)newAPIClient {
|
557 | return [[STPAPIClient alloc] initWithPublishableKey:[Stripe defaultPublishableKey]];
|
558 | }
|
559 |
|
560 | - (NSDictionary *)convertTokenObject:(STPToken*)token {
|
561 | NSMutableDictionary *result = [@{} mutableCopy];
|
562 |
|
563 | // Token
|
564 | [result setValue:token.tokenId forKey:@"tokenId"];
|
565 | [result setValue:@([token.created timeIntervalSince1970]) forKey:@"created"];
|
566 | [result setValue:@(token.livemode) forKey:@"livemode"];
|
567 |
|
568 | // Card
|
569 | if (token.card) {
|
570 | NSMutableDictionary *card = [@{} mutableCopy];
|
571 | [result setValue:card forKey:@"card"];
|
572 |
|
573 | [card setValue:token.card.stripeID forKey:@"cardId"];
|
574 |
|
575 | [card setValue:[self cardBrand:token.card.brand] forKey:@"brand"];
|
576 | [card setValue:[self cardFunding:token.card.funding] forKey:@"funding"];
|
577 | [card setValue:token.card.last4 forKey:@"last4"];
|
578 | [card setValue:token.card.dynamicLast4 forKey:@"dynamicLast4"];
|
579 | [card setValue:@(token.card.isApplePayCard) forKey:@"isApplePayCard"];
|
580 | [card setValue:@(token.card.expMonth) forKey:@"expMonth"];
|
581 | [card setValue:@(token.card.expYear) forKey:@"expYear"];
|
582 | [card setValue:token.card.country forKey:@"country"];
|
583 | [card setValue:token.card.currency forKey:@"currency"];
|
584 |
|
585 | [card setValue:token.card.name forKey:@"name"];
|
586 | [card setValue:token.card.address.line1 forKey:@"addressLine1"];
|
587 | [card setValue:token.card.address.line2 forKey:@"addressLine2"];
|
588 | [card setValue:token.card.address.city forKey:@"addressCity"];
|
589 | [card setValue:token.card.address.state forKey:@"addressState"];
|
590 | [card setValue:token.card.address.country forKey:@"addressCountry"];
|
591 | [card setValue:token.card.address.postalCode forKey:@"addressZip"];
|
592 | }
|
593 |
|
594 | // Bank Account
|
595 | if (token.bankAccount) {
|
596 | NSMutableDictionary *bankAccount = [@{} mutableCopy];
|
597 | [result setValue:bankAccount forKey:@"bankAccount"];
|
598 |
|
599 | NSString *bankAccountStatusString =
|
600 | [EXTPSConvert STPBankAccountStatusToString:token.bankAccount.status];
|
601 | [bankAccount setValue:bankAccountStatusString forKey:@"status"];
|
602 | [bankAccount setValue:token.bankAccount.country forKey:@"countryCode"];
|
603 | [bankAccount setValue:token.bankAccount.currency forKey:@"currency"];
|
604 | [bankAccount setValue:token.bankAccount.stripeID forKey:@"bankAccountId"];
|
605 | [bankAccount setValue:token.bankAccount.bankName forKey:@"bankName"];
|
606 | [bankAccount setValue:token.bankAccount.last4 forKey:@"last4"];
|
607 | [bankAccount setValue:token.bankAccount.accountHolderName forKey:@"accountHolderName"];
|
608 | NSString *bankAccountHolderTypeString =
|
609 | [EXTPSConvert STPBankAccountHolderTypeToString:token.bankAccount.accountHolderType];
|
610 | [bankAccount setValue:bankAccountHolderTypeString forKey:@"accountHolderType"];
|
611 | }
|
612 |
|
613 | return result;
|
614 | }
|
615 |
|
616 | - (NSDictionary *)convertSourceObject:(STPSource*)source {
|
617 | NSMutableDictionary *result = [@{} mutableCopy];
|
618 |
|
619 | // Source
|
620 | [result setValue:source.clientSecret forKey:@"clientSecret"];
|
621 | [result setValue:@([source.created timeIntervalSince1970]) forKey:@"created"];
|
622 | [result setValue:source.currency forKey:@"currency"];
|
623 | [result setValue:@(source.livemode) forKey:@"livemode"];
|
624 | [result setValue:source.amount forKey:@"amount"];
|
625 | [result setValue:source.stripeID forKey:@"sourceId"];
|
626 |
|
627 | // Flow
|
628 | [result setValue:[self sourceFlow:source.flow] forKey:@"flow"];
|
629 |
|
630 | // Metadata
|
631 | if (source.metadata) {
|
632 | [result setValue:source.metadata forKey:@"metadata"];
|
633 | }
|
634 |
|
635 | // Owner
|
636 | if (source.owner) {
|
637 | NSMutableDictionary *owner = [@{} mutableCopy];
|
638 | [result setValue:owner forKey:@"owner"];
|
639 |
|
640 | if (source.owner.address) {
|
641 | [owner setObject:source.owner.address forKey:@"address"];
|
642 | }
|
643 | [owner setValue:source.owner.email forKey:@"email"];
|
644 | [owner setValue:source.owner.name forKey:@"name"];
|
645 | [owner setValue:source.owner.phone forKey:@"phone"];
|
646 | if (source.owner.verifiedAddress) {
|
647 | [owner setObject:source.owner.verifiedAddress forKey:@"verifiedAddress"];
|
648 | }
|
649 | [owner setValue:source.owner.verifiedEmail forKey:@"verifiedEmail"];
|
650 | [owner setValue:source.owner.verifiedName forKey:@"verifiedName"];
|
651 | [owner setValue:source.owner.verifiedPhone forKey:@"verifiedPhone"];
|
652 | }
|
653 |
|
654 | // Details
|
655 | if (source.details) {
|
656 | [result setValue:source.details forKey:@"details"];
|
657 | }
|
658 |
|
659 | // Receiver
|
660 | if (source.receiver) {
|
661 | NSMutableDictionary *receiver = [@{} mutableCopy];
|
662 | [result setValue:receiver forKey:@"receiver"];
|
663 |
|
664 | [receiver setValue:source.receiver.address forKey:@"address"];
|
665 | [receiver setValue:source.receiver.amountCharged forKey:@"amountCharged"];
|
666 | [receiver setValue:source.receiver.amountReceived forKey:@"amountReceived"];
|
667 | [receiver setValue:source.receiver.amountReturned forKey:@"amountReturned"];
|
668 | }
|
669 |
|
670 | // Redirect
|
671 | if (source.redirect) {
|
672 | NSMutableDictionary *redirect = [@{} mutableCopy];
|
673 | [result setValue:redirect forKey:@"redirect"];
|
674 | NSString *returnURL = source.redirect.returnURL.absoluteString;
|
675 | [redirect setValue:returnURL forKey:@"returnURL"];
|
676 | NSString *url = source.redirect.url.absoluteString;
|
677 | [redirect setValue:url forKey:@"url"];
|
678 | [redirect setValue:[self sourceRedirectStatus:source.redirect.status] forKey:@"status"];
|
679 | }
|
680 |
|
681 | // Verification
|
682 | if (source.verification) {
|
683 | NSMutableDictionary *verification = [@{} mutableCopy];
|
684 | [result setValue:verification forKey:@"verification"];
|
685 |
|
686 | [verification setValue:source.verification.attemptsRemaining forKey:@"attemptsRemaining"];
|
687 | [verification setValue:[self sourceVerificationStatus:source.verification.status] forKey:@"status"];
|
688 | }
|
689 |
|
690 | // Status
|
691 | [result setValue:[self sourceStatus:source.status] forKey:@"status"];
|
692 |
|
693 | // Type
|
694 | [result setValue:[self sourceType:source.type] forKey:@"type"];
|
695 |
|
696 | // Usage
|
697 | [result setValue:[self sourceUsage:source.usage] forKey:@"usage"];
|
698 |
|
699 | // CardDetails
|
700 | if (source.cardDetails) {
|
701 | NSMutableDictionary *cardDetails = [@{} mutableCopy];
|
702 | [result setValue:cardDetails forKey:@"cardDetails"];
|
703 |
|
704 | [cardDetails setValue:source.cardDetails.last4 forKey:@"last4"];
|
705 | [cardDetails setValue:@(source.cardDetails.expMonth) forKey:@"expMonth"];
|
706 | [cardDetails setValue:@(source.cardDetails.expYear) forKey:@"expYear"];
|
707 | [cardDetails setValue:[self cardBrand:source.cardDetails.brand] forKey:@"brand"];
|
708 | [cardDetails setValue:[self cardFunding:source.cardDetails.funding] forKey:@"funding"];
|
709 | [cardDetails setValue:source.cardDetails.country forKey:@"country"];
|
710 | [cardDetails setValue:[self card3DSecureStatus:source.cardDetails.threeDSecure] forKey:@"threeDSecure"];
|
711 | }
|
712 |
|
713 | // SepaDebitDetails
|
714 | if (source.sepaDebitDetails) {
|
715 | NSMutableDictionary *sepaDebitDetails = [@{} mutableCopy];
|
716 | [result setValue:sepaDebitDetails forKey:@"sepaDebitDetails"];
|
717 |
|
718 | [sepaDebitDetails setValue:source.sepaDebitDetails.last4 forKey:@"last4"];
|
719 | [sepaDebitDetails setValue:source.sepaDebitDetails.bankCode forKey:@"bankCode"];
|
720 | [sepaDebitDetails setValue:source.sepaDebitDetails.country forKey:@"country"];
|
721 | [sepaDebitDetails setValue:source.sepaDebitDetails.fingerprint forKey:@"fingerprint"];
|
722 | [sepaDebitDetails setValue:source.sepaDebitDetails.mandateReference forKey:@"mandateReference"];
|
723 | NSString *mandateURL = source.sepaDebitDetails.mandateURL.absoluteString;
|
724 | [sepaDebitDetails setValue:mandateURL forKey:@"mandateURL"];
|
725 | }
|
726 |
|
727 | return result;
|
728 | }
|
729 |
|
730 | - (NSString *)cardBrand:(STPCardBrand)inputBrand {
|
731 | switch (inputBrand) {
|
732 | case STPCardBrandJCB:
|
733 | return @"JCB";
|
734 | case STPCardBrandAmex:
|
735 | return @"American Express";
|
736 | case STPCardBrandVisa:
|
737 | return @"Visa";
|
738 | case STPCardBrandDiscover:
|
739 | return @"Discover";
|
740 | case STPCardBrandDinersClub:
|
741 | return @"Diners Club";
|
742 | case STPCardBrandMasterCard:
|
743 | return @"MasterCard";
|
744 | default:
|
745 | return @"Unknown";
|
746 | }
|
747 | }
|
748 |
|
749 | - (NSString *)cardFunding:(STPCardFundingType)inputFunding {
|
750 | switch (inputFunding) {
|
751 | case STPCardFundingTypeDebit:
|
752 | return @"debit";
|
753 | case STPCardFundingTypeCredit:
|
754 | return @"credit";
|
755 | case STPCardFundingTypePrepaid:
|
756 | return @"prepaid";
|
757 | case STPCardFundingTypeOther:
|
758 | default:
|
759 | return @"unknown";
|
760 | }
|
761 | }
|
762 |
|
763 | - (NSString *)card3DSecureStatus:(STPSourceCard3DSecureStatus)inputStatus {
|
764 | switch (inputStatus) {
|
765 | case STPSourceCard3DSecureStatusRequired:
|
766 | return @"required";
|
767 | case STPSourceCard3DSecureStatusOptional:
|
768 | return @"optional";
|
769 | case STPSourceCard3DSecureStatusNotSupported:
|
770 | return @"notSupported";
|
771 | case STPSourceCard3DSecureStatusUnknown:
|
772 | default:
|
773 | return @"unknown";
|
774 | }
|
775 | }
|
776 |
|
777 | - (NSString *)sourceFlow:(STPSourceFlow)inputFlow {
|
778 | switch (inputFlow) {
|
779 | case STPSourceFlowNone:
|
780 | return @"none";
|
781 | case STPSourceFlowRedirect:
|
782 | return @"redirect";
|
783 | case STPSourceFlowCodeVerification:
|
784 | return @"codeVerification";
|
785 | case STPSourceFlowReceiver:
|
786 | return @"receiver";
|
787 | case STPSourceFlowUnknown:
|
788 | default:
|
789 | return @"unknown";
|
790 | }
|
791 | }
|
792 |
|
793 | - (NSString *)sourceRedirectStatus:(STPSourceRedirectStatus)inputStatus {
|
794 | switch (inputStatus) {
|
795 | case STPSourceRedirectStatusPending:
|
796 | return @"pending";
|
797 | case STPSourceRedirectStatusSucceeded:
|
798 | return @"succeeded";
|
799 | case STPSourceRedirectStatusFailed:
|
800 | return @"failed";
|
801 | case STPSourceRedirectStatusUnknown:
|
802 | default:
|
803 | return @"unknown";
|
804 | }
|
805 | }
|
806 |
|
807 | - (NSString *)sourceVerificationStatus:(STPSourceVerificationStatus)inputStatus {
|
808 | switch (inputStatus) {
|
809 | case STPSourceVerificationStatusPending:
|
810 | return @"pending";
|
811 | case STPSourceVerificationStatusSucceeded:
|
812 | return @"succeeded";
|
813 | case STPSourceVerificationStatusFailed:
|
814 | return @"failed";
|
815 | case STPSourceVerificationStatusUnknown:
|
816 | default:
|
817 | return @"unknown";
|
818 | }
|
819 | }
|
820 |
|
821 | - (NSString *)sourceStatus:(STPSourceStatus)inputStatus {
|
822 | switch (inputStatus) {
|
823 | case STPSourceStatusPending:
|
824 | return @"pending";
|
825 | case STPSourceStatusChargeable:
|
826 | return @"chargable";
|
827 | case STPSourceStatusConsumed:
|
828 | return @"consumed";
|
829 | case STPSourceStatusCanceled:
|
830 | return @"canceled";
|
831 | case STPSourceStatusFailed:
|
832 | return @"failed";
|
833 | case STPSourceStatusUnknown:
|
834 | default:
|
835 | return @"unknown";
|
836 | }
|
837 | }
|
838 |
|
839 | - (NSString *)sourceType:(STPSourceType)inputType {
|
840 | switch (inputType) {
|
841 | case STPSourceTypeBancontact:
|
842 | return @"bancontact";
|
843 | case STPSourceTypeGiropay:
|
844 | return @"giropay";
|
845 | case STPSourceTypeIDEAL:
|
846 | return @"ideal";
|
847 | case STPSourceTypeSEPADebit:
|
848 | return @"sepaDebit";
|
849 | case STPSourceTypeSofort:
|
850 | return @"sofort";
|
851 | case STPSourceTypeThreeDSecure:
|
852 | return @"threeDSecure";
|
853 | case STPSourceTypeAlipay:
|
854 | return @"alipay";
|
855 | case STPSourceTypeUnknown:
|
856 | default:
|
857 | return @"unknown";
|
858 | }
|
859 | }
|
860 |
|
861 | - (NSString *)sourceUsage:(STPSourceUsage)inputUsage {
|
862 | switch (inputUsage) {
|
863 | case STPSourceUsageReusable:
|
864 | return @"reusable";
|
865 | case STPSourceUsageSingleUse:
|
866 | return @"singleUse";
|
867 | case STPSourceUsageUnknown:
|
868 | default:
|
869 | return @"unknown";
|
870 | }
|
871 | }
|
872 |
|
873 | - (NSDictionary *)contactDetails:(PKContact*)inputContact {
|
874 | NSMutableDictionary *contactDetails = [[NSMutableDictionary alloc] init];
|
875 |
|
876 | if (inputContact.name) {
|
877 | [contactDetails setValue:[NSPersonNameComponentsFormatter localizedStringFromPersonNameComponents:inputContact.name style:NSPersonNameComponentsFormatterStyleDefault options:0] forKey:@"name"];
|
878 | }
|
879 |
|
880 | if (inputContact.phoneNumber) {
|
881 | [contactDetails setValue:[inputContact.phoneNumber stringValue] forKey:@"phoneNumber"];
|
882 | }
|
883 |
|
884 | if (inputContact.emailAddress) {
|
885 | [contactDetails setValue:inputContact.emailAddress forKey:@"emailAddress"];
|
886 | }
|
887 |
|
888 | if (inputContact.supplementarySubLocality) {
|
889 | [contactDetails setValue:inputContact.supplementarySubLocality forKey:@"supplementarySubLocality"];
|
890 | }
|
891 |
|
892 | for (NSString *elem in @[@"street", @"city", @"state", @"country", @"ISOCountryCode", @"postalCode"]) {
|
893 | if ([inputContact.postalAddress respondsToSelector:NSSelectorFromString(elem)]) {
|
894 | [contactDetails setValue:[inputContact.postalAddress valueForKey:elem] forKey:elem];
|
895 | }
|
896 | }
|
897 | if ([contactDetails count] == 0) {
|
898 | return nil;
|
899 | }
|
900 |
|
901 | return contactDetails;
|
902 | }
|
903 |
|
904 | - (NSDictionary *)shippingDetails:(PKShippingMethod*)inputShipping {
|
905 | NSMutableDictionary *shippingDetails = [[NSMutableDictionary alloc] init];
|
906 |
|
907 | if (inputShipping.label) {
|
908 | [shippingDetails setValue:inputShipping.label forKey:@"label"];
|
909 | }
|
910 |
|
911 | if (inputShipping.amount) {
|
912 | [shippingDetails setValue:[[self numberFormatter] stringFromNumber: inputShipping.amount] forKey:@"amount"];
|
913 | }
|
914 |
|
915 | if (inputShipping.detail) {
|
916 | [shippingDetails setValue:inputShipping.detail forKey:@"detail"];
|
917 | }
|
918 |
|
919 | if (inputShipping.identifier) {
|
920 | [shippingDetails setValue:inputShipping.identifier forKey:@"id"];
|
921 | }
|
922 |
|
923 | if ([shippingDetails count] == 0) {
|
924 | return nil;
|
925 | }
|
926 |
|
927 | return shippingDetails;
|
928 | }
|
929 |
|
930 | - (PKAddressField)applePayAddressFields:(NSArray <NSString *> *)addressFieldStrings {
|
931 | PKAddressField addressField = PKAddressFieldNone;
|
932 |
|
933 | for (NSString *addressFieldString in addressFieldStrings) {
|
934 | addressField |= [self applePayAddressField:addressFieldString];
|
935 | }
|
936 |
|
937 | return addressField;
|
938 | }
|
939 |
|
940 | - (PKAddressField)applePayAddressField:(NSString *)addressFieldString {
|
941 | PKAddressField addressField = PKAddressFieldNone;
|
942 | if ([addressFieldString isEqualToString:@"postal_address"]) {
|
943 | addressField = PKAddressFieldPostalAddress;
|
944 | }
|
945 | if ([addressFieldString isEqualToString:@"phone"]) {
|
946 | addressField = PKAddressFieldPhone;
|
947 | }
|
948 | if ([addressFieldString isEqualToString:@"email"]) {
|
949 | addressField = PKAddressFieldEmail;
|
950 | }
|
951 | if ([addressFieldString isEqualToString:@"name"]) {
|
952 | addressField = PKAddressFieldName;
|
953 | }
|
954 | if ([addressFieldString isEqualToString:@"all"]) {
|
955 | addressField = PKAddressFieldAll;
|
956 | }
|
957 | return addressField;
|
958 | }
|
959 |
|
960 | - (PKShippingType)applePayShippingType:(NSString*)inputType {
|
961 | PKShippingType shippingType = PKShippingTypeShipping;
|
962 | if ([inputType isEqualToString:@"delivery"]) {
|
963 | shippingType = PKShippingTypeDelivery;
|
964 | }
|
965 | if ([inputType isEqualToString:@"store_pickup"]) {
|
966 | shippingType = PKShippingTypeStorePickup;
|
967 | }
|
968 | if ([inputType isEqualToString:@"service_pickup"]) {
|
969 | shippingType = PKShippingTypeServicePickup;
|
970 | }
|
971 |
|
972 | return shippingType;
|
973 | }
|
974 |
|
975 | - (STPBillingAddressFields)billingType:(NSString*)inputType {
|
976 | if ([inputType isEqualToString:@"zip"]) {
|
977 | return STPBillingAddressFieldsZip;
|
978 | }
|
979 | if ([inputType isEqualToString:@"full"]) {
|
980 | return STPBillingAddressFieldsFull;
|
981 | }
|
982 | return STPBillingAddressFieldsNone;
|
983 | }
|
984 |
|
985 | - (STPUserInformation *)userInformation:(NSDictionary*)inputInformation {
|
986 | STPUserInformation *userInformation = [[STPUserInformation alloc] init];
|
987 |
|
988 | [userInformation setBillingAddress: [self address:inputInformation[@"billingAddress"]]];
|
989 | [userInformation setShippingAddress: [self address:inputInformation[@"shippingAddress"]]];
|
990 |
|
991 | return userInformation;
|
992 | }
|
993 |
|
994 | - (STPAddress *)address:(NSDictionary*)inputAddress {
|
995 | STPAddress *address = [[STPAddress alloc] init];
|
996 |
|
997 | [address setName:inputAddress[@"name"]];
|
998 | [address setLine1:inputAddress[@"line1"]];
|
999 | [address setLine2:inputAddress[@"line2"]];
|
1000 | [address setCity:inputAddress[@"city"]];
|
1001 | [address setState:inputAddress[@"state"]];
|
1002 | [address setPostalCode:inputAddress[@"postalCode"]];
|
1003 | [address setCountry:inputAddress[@"country"]];
|
1004 | [address setPhone:inputAddress[@"phone"]];
|
1005 | [address setEmail:inputAddress[@"email"]];
|
1006 |
|
1007 | return address;
|
1008 | }
|
1009 |
|
1010 | - (STPTheme *)formTheme:(NSDictionary*)options {
|
1011 | STPTheme *theme = [[STPTheme alloc] init];
|
1012 |
|
1013 | [theme setPrimaryBackgroundColor:[EXTPSConvert UIColor:options[@"primaryBackgroundColor"]]];
|
1014 | [theme setSecondaryBackgroundColor:[EXTPSConvert UIColor:options[@"secondaryBackgroundColor"]]];
|
1015 | [theme setPrimaryForegroundColor:[EXTPSConvert UIColor:options[@"primaryForegroundColor"]]];
|
1016 | [theme setSecondaryForegroundColor:[EXTPSConvert UIColor:options[@"secondaryForegroundColor"]]];
|
1017 | [theme setAccentColor:[EXTPSConvert UIColor:options[@"accentColor"]]];
|
1018 | [theme setErrorColor:[EXTPSConvert UIColor:options[@"errorColor"]]];
|
1019 | [theme setErrorColor:[EXTPSConvert UIColor:options[@"errorColor"]]];
|
1020 | // TODO: process font vars
|
1021 |
|
1022 | return theme;
|
1023 | }
|
1024 |
|
1025 | - (UIModalPresentationStyle)formPresentation:(NSString*)inputType {
|
1026 | if ([inputType isEqualToString:@"pageSheet"])
|
1027 | return UIModalPresentationPageSheet;
|
1028 | if ([inputType isEqualToString:@"formSheet"])
|
1029 | return UIModalPresentationFormSheet;
|
1030 |
|
1031 | return UIModalPresentationFullScreen;
|
1032 | }
|
1033 |
|
1034 | + (NSArray <NSString *> *)supportedPaymentNetworksStrings {
|
1035 | return @[
|
1036 | TPSPaymentNetworkAmex,
|
1037 | TPSPaymentNetworkDiscover,
|
1038 | TPSPaymentNetworkMasterCard,
|
1039 | TPSPaymentNetworkVisa,
|
1040 | ];
|
1041 | }
|
1042 |
|
1043 | - (NSArray <PKPaymentNetwork> *)paymentNetworks:(NSArray <NSString *> *)paymentNetworkStrings {
|
1044 | NSMutableArray <PKPaymentNetwork> *results = [@[] mutableCopy];
|
1045 |
|
1046 | for (NSString *paymentNetworkString in paymentNetworkStrings) {
|
1047 | PKPaymentNetwork paymentNetwork = [self paymentNetwork:paymentNetworkString];
|
1048 | if (paymentNetwork) {
|
1049 | [results addObject:paymentNetwork];
|
1050 | }
|
1051 | }
|
1052 |
|
1053 | return [results copy];
|
1054 | }
|
1055 |
|
1056 | - (PKPaymentNetwork)paymentNetwork:(NSString *)paymentNetworkString {
|
1057 | static NSDictionary *paymentNetworksMap;
|
1058 | static dispatch_once_t onceToken;
|
1059 | dispatch_once(&onceToken, ^{
|
1060 | NSMutableDictionary *mutableMap = [@{} mutableCopy];
|
1061 |
|
1062 | if ((&PKPaymentNetworkAmex) != NULL) {
|
1063 | mutableMap[TPSPaymentNetworkAmex] = PKPaymentNetworkAmex;
|
1064 | }
|
1065 |
|
1066 | if ((&PKPaymentNetworkDiscover) != NULL) {
|
1067 | mutableMap[TPSPaymentNetworkDiscover] = PKPaymentNetworkDiscover;
|
1068 | }
|
1069 |
|
1070 | if ((&PKPaymentNetworkMasterCard) != NULL) {
|
1071 | mutableMap[TPSPaymentNetworkMasterCard] = PKPaymentNetworkMasterCard;
|
1072 | }
|
1073 |
|
1074 | if ((&PKPaymentNetworkVisa) != NULL) {
|
1075 | mutableMap[TPSPaymentNetworkVisa] = PKPaymentNetworkVisa;
|
1076 | }
|
1077 |
|
1078 | paymentNetworksMap = [mutableMap copy];
|
1079 | });
|
1080 |
|
1081 | return paymentNetworksMap[paymentNetworkString];
|
1082 | }
|
1083 |
|
1084 | - (NSNumberFormatter *)numberFormatter {
|
1085 | static NSNumberFormatter *kSharedFormatter;
|
1086 | static dispatch_once_t onceToken;
|
1087 | dispatch_once(&onceToken, ^{
|
1088 | kSharedFormatter = [[NSNumberFormatter alloc] init];
|
1089 | [kSharedFormatter setPositiveFormat:@"$0.00"];
|
1090 | });
|
1091 | return kSharedFormatter;
|
1092 | }
|
1093 |
|
1094 | + (BOOL)requiresMainQueueSetup
|
1095 | {
|
1096 | return YES;
|
1097 | }
|
1098 |
|
1099 | - (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
|
1100 | {
|
1101 | _moduleRegistry = moduleRegistry;
|
1102 | }
|
1103 |
|
1104 | @end
|