BTCard.m 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #import "BTCard_Internal.h"
  2. #import "BTJSON.h"
  3. @interface BTCard ()
  4. @property (nonatomic, strong) NSMutableDictionary *mutableParameters;
  5. @property (nonatomic, strong, readonly) NSString *cardTokenizationGraphQLMutation;
  6. @end
  7. @implementation BTCard
  8. - (instancetype)init {
  9. return [self initWithParameters:@{}];
  10. }
  11. - (nonnull instancetype)initWithParameters:(NSDictionary *)parameters {
  12. if (self = [super init]) {
  13. _mutableParameters = [parameters mutableCopy];
  14. _number = parameters[@"number"];
  15. NSArray *components = [parameters[@"expiration_date"] componentsSeparatedByString:@"/"];
  16. if (components.count == 2) {
  17. _expirationMonth = components[0];
  18. _expirationYear = components[1];
  19. }
  20. _postalCode = parameters[@"billing_address"][@"postal_code"];
  21. _cvv = parameters[@"cvv"];
  22. _streetAddress = parameters[@"billing_address"][@"street_address"];
  23. _extendedAddress = parameters[@"billing_address"][@"extended_address"];
  24. _locality = parameters[@"billing_address"][@"locality"];
  25. _region = parameters[@"billing_address"][@"region"];
  26. _countryName = parameters[@"billing_address"][@"country_name"];
  27. _countryCodeAlpha2 = parameters[@"billing_address"][@"country_code_alpha2"];
  28. _countryCodeAlpha3 = parameters[@"billing_address"][@"country_code_alpha3"];
  29. _countryCodeNumeric = parameters[@"billing_address"][@"country_code_numeric"];
  30. _cardholderName = parameters[@"cardholder_name"];
  31. _firstName = parameters[@"billing_address"][@"first_name"];
  32. _lastName = parameters[@"billing_address"][@"last_name"];
  33. _company = parameters[@"billing_address"][@"company"];
  34. _shouldValidate = [parameters[@"options"][@"validate"] boolValue];
  35. }
  36. return self;
  37. }
  38. - (instancetype)initWithNumber:(NSString *)number
  39. expirationMonth:(NSString *)expirationMonth
  40. expirationYear:(NSString *)expirationYear
  41. cvv:(NSString *)cvv
  42. {
  43. if (self = [self initWithParameters:@{}]) {
  44. _number = number;
  45. _expirationMonth = expirationMonth;
  46. _expirationYear = expirationYear;
  47. _cvv = cvv;
  48. }
  49. return self;
  50. }
  51. #pragma mark -
  52. - (NSDictionary *)parameters {
  53. NSMutableDictionary *p = [self.mutableParameters mutableCopy];
  54. if (self.number) {
  55. p[@"number"] = self.number;
  56. }
  57. if (self.expirationMonth) {
  58. p[@"expiration_month"] = self.expirationMonth;
  59. }
  60. if (self.expirationYear) {
  61. p[@"expiration_year"] = self.expirationYear;
  62. }
  63. if (self.cardholderName) {
  64. p[@"cardholder_name"] = self.cardholderName;
  65. }
  66. if (self.expirationMonth && self.expirationYear) {
  67. p[@"expiration_date"] = [NSString stringWithFormat:@"%@/%@", self.expirationMonth, self.expirationYear];
  68. }
  69. if (self.cvv) {
  70. p[@"cvv"] = self.cvv;
  71. }
  72. if (self.cardholderName) {
  73. p[@"cardholder_name"] = self.cardholderName;
  74. }
  75. NSMutableDictionary *billingAddressDictionary = [NSMutableDictionary new];
  76. if ([p[@"billing_address"] isKindOfClass:[NSDictionary class]]) {
  77. [billingAddressDictionary addEntriesFromDictionary:p[@"billing_address"]];
  78. }
  79. if (self.firstName) {
  80. billingAddressDictionary[@"first_name"] = self.firstName;
  81. }
  82. if (self.lastName) {
  83. billingAddressDictionary[@"last_name"] = self.lastName;
  84. }
  85. if (self.company) {
  86. billingAddressDictionary[@"company"] = self.company;
  87. }
  88. if (self.postalCode) {
  89. billingAddressDictionary[@"postal_code"] = self.postalCode;
  90. }
  91. if (self.streetAddress) {
  92. billingAddressDictionary[@"street_address"] = self.streetAddress;
  93. }
  94. if (self.extendedAddress) {
  95. billingAddressDictionary[@"extended_address"] = self.extendedAddress;
  96. }
  97. if (self.locality) {
  98. billingAddressDictionary[@"locality"] = self.locality;
  99. }
  100. if (self.region) {
  101. billingAddressDictionary[@"region"] = self.region;
  102. }
  103. if (self.countryName) {
  104. billingAddressDictionary[@"country_name"] = self.countryName;
  105. }
  106. if (self.countryCodeAlpha2) {
  107. billingAddressDictionary[@"country_code_alpha2"] = self.countryCodeAlpha2;
  108. }
  109. if (self.countryCodeAlpha3) {
  110. billingAddressDictionary[@"country_code_alpha3"] = self.countryCodeAlpha3;
  111. }
  112. if (self.countryCodeNumeric) {
  113. billingAddressDictionary[@"country_code_numeric"] = self.countryCodeNumeric;
  114. }
  115. if (billingAddressDictionary.count > 0) {
  116. p[@"billing_address"] = [billingAddressDictionary copy];
  117. }
  118. NSMutableDictionary *optionsDictionary = [NSMutableDictionary new];
  119. if ([p[@"options"] isKindOfClass:[NSDictionary class]]) {
  120. [optionsDictionary addEntriesFromDictionary:p[@"options"]];
  121. }
  122. optionsDictionary[@"validate"] = @(self.shouldValidate);
  123. p[@"options"] = [optionsDictionary copy];
  124. return [p copy];
  125. }
  126. - (NSDictionary *)graphQLParameters {
  127. NSMutableDictionary *inputDictionary = [NSMutableDictionary new];
  128. NSMutableDictionary *cardDictionary = [NSMutableDictionary new];
  129. inputDictionary[@"creditCard"] = cardDictionary;
  130. if (self.number) {
  131. cardDictionary[@"number"] = self.number;
  132. }
  133. if (self.expirationMonth) {
  134. cardDictionary[@"expirationMonth"] = self.expirationMonth;
  135. }
  136. if (self.expirationYear) {
  137. cardDictionary[@"expirationYear"] = self.expirationYear;
  138. }
  139. if (self.cvv) {
  140. cardDictionary[@"cvv"] = self.cvv;
  141. }
  142. if (self.cardholderName) {
  143. cardDictionary[@"cardholderName"] = self.cardholderName;
  144. }
  145. NSMutableDictionary *billingAddressDictionary = [NSMutableDictionary new];
  146. if ([cardDictionary[@"billingAddress"] isKindOfClass:[NSDictionary class]]) {
  147. [billingAddressDictionary addEntriesFromDictionary:cardDictionary[@"billingAddress"]];
  148. }
  149. if (self.firstName) {
  150. billingAddressDictionary[@"firstName"] = self.firstName;
  151. }
  152. if (self.lastName) {
  153. billingAddressDictionary[@"lastName"] = self.lastName;
  154. }
  155. if (self.company) {
  156. billingAddressDictionary[@"company"] = self.company;
  157. }
  158. if (self.postalCode) {
  159. billingAddressDictionary[@"postalCode"] = self.postalCode;
  160. }
  161. if (self.streetAddress) {
  162. billingAddressDictionary[@"streetAddress"] = self.streetAddress;
  163. }
  164. if (self.extendedAddress) {
  165. billingAddressDictionary[@"extendedAddress"] = self.extendedAddress;
  166. }
  167. if (self.locality) {
  168. billingAddressDictionary[@"locality"] = self.locality;
  169. }
  170. if (self.region) {
  171. billingAddressDictionary[@"region"] = self.region;
  172. }
  173. if (self.countryName) {
  174. billingAddressDictionary[@"countryName"] = self.countryName;
  175. }
  176. if (self.countryCodeAlpha2) {
  177. billingAddressDictionary[@"countryCodeAlpha2"] = self.countryCodeAlpha2;
  178. }
  179. if (self.countryCodeAlpha3) {
  180. billingAddressDictionary[@"countryCode"] = self.countryCodeAlpha3;
  181. }
  182. if (self.countryCodeNumeric) {
  183. billingAddressDictionary[@"countryCodeNumeric"] = self.countryCodeNumeric;
  184. }
  185. if (billingAddressDictionary.count > 0) {
  186. cardDictionary[@"billingAddress"] = [billingAddressDictionary copy];
  187. }
  188. NSMutableDictionary *optionsDictionary = [NSMutableDictionary new];
  189. if ([inputDictionary[@"options"] isKindOfClass:[NSDictionary class]]) {
  190. [optionsDictionary addEntriesFromDictionary:inputDictionary[@"options"]];
  191. }
  192. optionsDictionary[@"validate"] = @(self.shouldValidate);
  193. inputDictionary[@"options"] = [optionsDictionary copy];
  194. NSMutableDictionary *variables = [@{ @"input": [inputDictionary copy] } mutableCopy];
  195. if (self.authenticationInsightRequested) {
  196. variables[@"authenticationInsightInput"] = self.merchantAccountId ? @{ @"merchantAccountId": self.merchantAccountId } : @{};
  197. }
  198. return @{
  199. @"operationName": @"TokenizeCreditCard",
  200. @"query": self.cardTokenizationGraphQLMutation,
  201. @"variables": variables
  202. };
  203. }
  204. - (NSString *)cardTokenizationGraphQLMutation {
  205. NSMutableString *mutation = [@"mutation TokenizeCreditCard($input: TokenizeCreditCardInput!" mutableCopy];
  206. if (self.authenticationInsightRequested) {
  207. [mutation appendString:@", $authenticationInsightInput: AuthenticationInsightInput!"];
  208. }
  209. [mutation appendString:@""
  210. ") {"
  211. " tokenizeCreditCard(input: $input) {"
  212. " token"
  213. " creditCard {"
  214. " brand"
  215. " expirationMonth"
  216. " expirationYear"
  217. " cardholderName"
  218. " last4"
  219. " bin"
  220. " binData {"
  221. " prepaid"
  222. " healthcare"
  223. " debit"
  224. " durbinRegulated"
  225. " commercial"
  226. " payroll"
  227. " issuingBank"
  228. " countryOfIssuance"
  229. " productId"
  230. " }"
  231. " }"
  232. ];
  233. if (self.authenticationInsightRequested) {
  234. [mutation appendString:@""
  235. " authenticationInsight(input: $authenticationInsightInput) {"
  236. " customerAuthenticationRegulationEnvironment"
  237. " }"
  238. ];
  239. }
  240. [mutation appendString:@""
  241. " }"
  242. "}"
  243. ];
  244. return mutation;
  245. }
  246. @end