diff --git a/README.md b/README.md index 5d4ed7e..fb334dd 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The preferred method of installing BlockChyp is via cocoapods. Add the following dependency to your Podfile and type `pod install`. ``` - pod 'BlockChyp', '~> 2.19.0' + pod 'BlockChyp', '~> 2.20.1' ``` Note: If you're using Swift, you'll need to make sure dynamic frameworks are turned @@ -630,6 +630,96 @@ class ExampleClass { +#### Card Metadata + + + +* **API Credential Types:** Merchant +* **Required Role:** Payment API Access + +This API allows you to retrieve card metadata. + +Card metadata requests can use a payment terminal to retrieve metadata or +use a previously enrolled payment token. + +**Terminal Transactions** + +For terminal transactions, make sure you pass in the terminal name using the `terminalName` property. + +**Token Transactions** + +If you have a payment token, omit the `terminalName` property and pass in the token with the `token` +property instead. + +**Card Numbers and Mag Stripes** + +You can also pass in PANs and Mag Stripes, but you probably shouldn't, as this will +put you in PCI scope and the most common vector for POS breaches is keylogging. +If you use terminals for manual card entry, you'll bypass any keyloggers that +might be maliciously running on the point-of-sale system. + + + +##### From Objective-C: + +```objective-c +#import +#import + +int main (int argc, const char * argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + BlockChyp *client = [[BlockChyp alloc] + initWithApiKey:@"SPBXTSDAQVFFX5MGQMUMIRINVI" + bearerToken:@"7BXBTBUPSL3BP7I6Z2CFU6H3WQ" + signingKey:@"bcae3708938cb8004ab1278e6c0fcd68f9d815e1c3c86228d028242b147af58e"]; + + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + request["test"] = true + request["terminalName"] = "Test Terminal" + [client cardMetadataWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { + NSNumber *success = [response objectForKey:@"success"]; + if (success.boolValue) { + NSLog(@"success"); + } + }]; + [pool drain]; + return 0; +} + +``` + +##### From Swift: + +```swift +import BlockChyp + +class ExampleClass { + + func example() { + let client = BlockChyp.init( + apiKey: "ZN5WQGX5PN6BE2MF75CEAWRETM", + bearerToken: "SVVHJCYVFWJR2QKYKFWMZQVZL4", + signingKey: "7c1b9e4d1308e7bbe76a1920ddd9449ce50af2629f6bb70ed3c110365935970b" + ) + + var request: [String:Any] = [:] + request["test"] = true + request["terminalName"] = "Test Terminal" + client.cardMetadata(withRequest: request, handler: { (request, response, error) in + let approved = response["success"] as? Bool + if (approved.unsafelyUnwrapped) { + NSLog("success") + } + }) + } + + +``` + + + #### Time Out Reversal @@ -7239,6 +7329,7 @@ int main (int argc, const char * argv[]) signingKey:@"bcae3708938cb8004ab1278e6c0fcd68f9d815e1c3c86228d028242b147af58e"]; NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + request["merchantId"] = "" [client merchantCredentialGenerationWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { NSNumber *success = [response objectForKey:@"success"]; if (success.boolValue) { @@ -7266,6 +7357,7 @@ class ExampleClass { ) var request: [String:Any] = [:] + request["merchantId"] = "" client.merchantCredentialGeneration(withRequest: request, handler: { (request, response, error) in let approved = response["success"] as? Bool if (approved.unsafelyUnwrapped) { @@ -7279,6 +7371,86 @@ class ExampleClass { +#### Submit Application + + + +* **API Credential Types:** Partner +* **Required Role:** INVITE MERCHANT + +This is a partner level API that can be used to submit applications to add new merchant accounts. The application requires a significant amount of detailed information about the merchant and their business. Rather than providing an exhaustive list of required fields, we recommend submitting as much information as possible in your initial request. + +If any required fields are missing or if there are any validation errors, the API will return specific error messages indicating which fields need to be addressed. Simply review these validation errors, fill in the missing information or correct any errors, and resubmit the application. + +Key areas of information include: +- Business details (name, type, tax information) +- Contact information +- Address information (physical and mailing) +- Owner details +- Bank account information +- Transaction volume estimates +- Operational settings (timezone, batch close time, etc.) + +**Note:** Some fields may be conditionally required based on the values of other fields. The validation process will guide you through ensuring all necessary information is provided. + + + +##### From Objective-C: + +```objective-c +#import +#import + +int main (int argc, const char * argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + BlockChyp *client = [[BlockChyp alloc] + initWithApiKey:@"SPBXTSDAQVFFX5MGQMUMIRINVI" + bearerToken:@"7BXBTBUPSL3BP7I6Z2CFU6H3WQ" + signingKey:@"bcae3708938cb8004ab1278e6c0fcd68f9d815e1c3c86228d028242b147af58e"]; + + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + [client submitApplicationWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { + NSNumber *success = [response objectForKey:@"success"]; + if (success.boolValue) { + NSLog(@"Success"); + } + }]; + [pool drain]; + return 0; +} + +``` + +##### From Swift: + +```swift +import BlockChyp + +class ExampleClass { + + func example() { + let client = BlockChyp.init( + apiKey: "ZN5WQGX5PN6BE2MF75CEAWRETM", + bearerToken: "SVVHJCYVFWJR2QKYKFWMZQVZL4", + signingKey: "7c1b9e4d1308e7bbe76a1920ddd9449ce50af2629f6bb70ed3c110365935970b" + ) + + var request: [String:Any] = [:] + client.submitApplication(withRequest: request, handler: { (request, response, error) in + let approved = response["success"] as? Bool + if (approved.unsafelyUnwrapped) { + NSLog("Success") + } + }) + } + + +``` + + + diff --git a/blockchyp-ios-examples/CardMetadataExample.m b/blockchyp-ios-examples/CardMetadataExample.m new file mode 100644 index 0000000..648453c --- /dev/null +++ b/blockchyp-ios-examples/CardMetadataExample.m @@ -0,0 +1,24 @@ +#import +#import + +int main (int argc, const char * argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + BlockChyp *client = [[BlockChyp alloc] + initWithApiKey:@"SPBXTSDAQVFFX5MGQMUMIRINVI" + bearerToken:@"7BXBTBUPSL3BP7I6Z2CFU6H3WQ" + signingKey:@"bcae3708938cb8004ab1278e6c0fcd68f9d815e1c3c86228d028242b147af58e"]; + + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + request["test"] = true + request["terminalName"] = "Test Terminal" + [client cardMetadataWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { + NSNumber *success = [response objectForKey:@"success"]; + if (success.boolValue) { + NSLog(@"success"); + } + }]; + [pool drain]; + return 0; +} diff --git a/blockchyp-ios-examples/CardMetadataExample.swift b/blockchyp-ios-examples/CardMetadataExample.swift new file mode 100644 index 0000000..6997cb2 --- /dev/null +++ b/blockchyp-ios-examples/CardMetadataExample.swift @@ -0,0 +1,22 @@ +import BlockChyp + +class ExampleClass { + + func example() { + let client = BlockChyp.init( + apiKey: "ZN5WQGX5PN6BE2MF75CEAWRETM", + bearerToken: "SVVHJCYVFWJR2QKYKFWMZQVZL4", + signingKey: "7c1b9e4d1308e7bbe76a1920ddd9449ce50af2629f6bb70ed3c110365935970b" + ) + + var request: [String:Any] = [:] + request["test"] = true + request["terminalName"] = "Test Terminal" + client.cardMetadata(withRequest: request, handler: { (request, response, error) in + let approved = response["success"] as? Bool + if (approved.unsafelyUnwrapped) { + NSLog("success") + } + }) + } + diff --git a/blockchyp-ios-examples/MerchantCredentialGenerationExample.m b/blockchyp-ios-examples/MerchantCredentialGenerationExample.m index 3a396ac..dcee81a 100644 --- a/blockchyp-ios-examples/MerchantCredentialGenerationExample.m +++ b/blockchyp-ios-examples/MerchantCredentialGenerationExample.m @@ -11,6 +11,7 @@ int main (int argc, const char * argv[]) signingKey:@"bcae3708938cb8004ab1278e6c0fcd68f9d815e1c3c86228d028242b147af58e"]; NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + request["merchantId"] = "" [client merchantCredentialGenerationWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { NSNumber *success = [response objectForKey:@"success"]; if (success.boolValue) { diff --git a/blockchyp-ios-examples/MerchantCredentialGenerationExample.swift b/blockchyp-ios-examples/MerchantCredentialGenerationExample.swift index 7b36464..bc769c1 100644 --- a/blockchyp-ios-examples/MerchantCredentialGenerationExample.swift +++ b/blockchyp-ios-examples/MerchantCredentialGenerationExample.swift @@ -10,6 +10,7 @@ class ExampleClass { ) var request: [String:Any] = [:] + request["merchantId"] = "" client.merchantCredentialGeneration(withRequest: request, handler: { (request, response, error) in let approved = response["success"] as? Bool if (approved.unsafelyUnwrapped) { diff --git a/blockchyp-ios-examples/SubmitApplicationExample.m b/blockchyp-ios-examples/SubmitApplicationExample.m new file mode 100644 index 0000000..df9ccb6 --- /dev/null +++ b/blockchyp-ios-examples/SubmitApplicationExample.m @@ -0,0 +1,22 @@ +#import +#import + +int main (int argc, const char * argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + BlockChyp *client = [[BlockChyp alloc] + initWithApiKey:@"SPBXTSDAQVFFX5MGQMUMIRINVI" + bearerToken:@"7BXBTBUPSL3BP7I6Z2CFU6H3WQ" + signingKey:@"bcae3708938cb8004ab1278e6c0fcd68f9d815e1c3c86228d028242b147af58e"]; + + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + [client submitApplicationWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { + NSNumber *success = [response objectForKey:@"success"]; + if (success.boolValue) { + NSLog(@"Success"); + } + }]; + [pool drain]; + return 0; +} diff --git a/blockchyp-ios-examples/SubmitApplicationExample.swift b/blockchyp-ios-examples/SubmitApplicationExample.swift new file mode 100644 index 0000000..8097088 --- /dev/null +++ b/blockchyp-ios-examples/SubmitApplicationExample.swift @@ -0,0 +1,20 @@ +import BlockChyp + +class ExampleClass { + + func example() { + let client = BlockChyp.init( + apiKey: "ZN5WQGX5PN6BE2MF75CEAWRETM", + bearerToken: "SVVHJCYVFWJR2QKYKFWMZQVZL4", + signingKey: "7c1b9e4d1308e7bbe76a1920ddd9449ce50af2629f6bb70ed3c110365935970b" + ) + + var request: [String:Any] = [:] + client.submitApplication(withRequest: request, handler: { (request, response, error) in + let approved = response["success"] as? Bool + if (approved.unsafelyUnwrapped) { + NSLog("Success") + } + }) + } + diff --git a/blockchyp-ios/BlockChyp.podspec b/blockchyp-ios/BlockChyp.podspec index cff5127..4eb37e4 100644 --- a/blockchyp-ios/BlockChyp.podspec +++ b/blockchyp-ios/BlockChyp.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |spec| spec.name = "BlockChyp" - spec.version = "2.19.0" + spec.version = "2.20.1" spec.summary = "BlockChyp SDK for iOS Developers." spec.description = <<-DESC This is the SDK for iOS. Like all BlockChyp SDKs, it provides a full diff --git a/blockchyp-ios/BlockChyp/BlockChyp.h b/blockchyp-ios/BlockChyp/BlockChyp.h index aff5c08..0079404 100644 --- a/blockchyp-ios/BlockChyp/BlockChyp.h +++ b/blockchyp-ios/BlockChyp/BlockChyp.h @@ -29,6 +29,9 @@ NS_ASSUME_NONNULL_BEGIN // Adds a new payment method to the token vault. -(void)enrollWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; +// Retrieves card metadata. +-(void)cardMetadataWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; + // Activates or recharges a gift card. -(void)giftActivateWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; @@ -177,6 +180,9 @@ NS_ASSUME_NONNULL_BEGIN // Generates and returns api credentials for a given merchant. -(void)merchantCredentialGenerationWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; +// Submits and application to add a new merchant account. +-(void)submitApplicationWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; + // Adds a test merchant account. -(void)getMerchantsWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; diff --git a/blockchyp-ios/BlockChyp/BlockChyp.m b/blockchyp-ios/BlockChyp/BlockChyp.m index 6e88844..283abf0 100644 --- a/blockchyp-ios/BlockChyp/BlockChyp.m +++ b/blockchyp-ios/BlockChyp/BlockChyp.m @@ -50,6 +50,13 @@ -(void)enrollWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHan } +// Retrieves card metadata. +-(void)cardMetadataWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; { + + [self routeTerminalRequestWith:request terminalPath:@"/api/card-metadata" gatewayPath:@"/api/card-metadata" method:@"POST" handler:handler]; + +} + // Activates or recharges a gift card. -(void)giftActivateWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler; { @@ -375,6 +382,14 @@ -(void)merchantCredentialGenerationWithRequest:(NSDictionary *)request handler:( } +// Submits and application to add a new merchant account. +-(void)submitApplicationWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler { + + [self routeDashboardRequestWith:request path:@"/api/submit-application" method:@"POST" handler:handler]; + +} + + // Adds a test merchant account. -(void)getMerchantsWithRequest:(NSDictionary *)request handler:(BlockChypCompletionHandler)handler { diff --git a/blockchyp-ios/Tests/SubmitApplicationTest.m b/blockchyp-ios/Tests/SubmitApplicationTest.m new file mode 100644 index 0000000..abec612 --- /dev/null +++ b/blockchyp-ios/Tests/SubmitApplicationTest.m @@ -0,0 +1,161 @@ +// Copyright 2019-2022 BlockChyp, Inc. All rights reserved. Use of this code +// is governed by a license that can be found in the LICENSE file. +// +// This file was generated automatically by the BlockChyp SDK Generator. +// Changes to this file will be lost every time the code is regenerated. + +#import "BlockChypTest.h" + +@interface SubmitApplicationTest : BlockChypTest + + + +@end + +@implementation SubmitApplicationTest + +- (void)setUp { + + TestConfiguration *config = [self loadConfiguration]; + BlockChyp *client = [[BlockChyp alloc] initWithApiKey:config.apiKey bearerToken:config.bearerToken signingKey:config.signingKey]; + client.gatewayHost = config.gatewayHost; + client.testGatewayHost = config.testGatewayHost; + client.dashboardHost = config.dashboardHost; + + NSDictionary *profile = [config.profiles objectForKey:@"partner"]; + client.apiKey = (NSString*) [profile objectForKey:@"apiKey"]; + client.bearerToken = (NSString*) [profile objectForKey:@"bearerToken"]; + client.signingKey = (NSString*) [profile objectForKey:@"signingKey"]; + + +} + +- (void)tearDown { + +} + +- (void)testSubmitApplication{ + + TestConfiguration *config = [self loadConfiguration]; + BlockChyp *client = [[BlockChyp alloc] initWithApiKey:config.apiKey bearerToken:config.bearerToken signingKey:config.signingKey]; + client.gatewayHost = config.gatewayHost; + client.testGatewayHost = config.testGatewayHost; + client.dashboardHost = config.dashboardHost; + + NSDictionary *profile = [config.profiles objectForKey:@"partner"]; + client.apiKey = (NSString*) [profile objectForKey:@"apiKey"]; + client.bearerToken = (NSString*) [profile objectForKey:@"bearerToken"]; + client.signingKey = (NSString*) [profile objectForKey:@"signingKey"]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"SubmitApplication Test"]; + + NSMutableDictionary *request = [[NSMutableDictionary alloc] init]; + request[@"test"] = @YES; + request[@"inviteCode"] = @"asdf"; + request[@"dbaName"] = @"BlockChyp"; + request[@"corporateName"] = @"BlockChyp Inc."; + request[@"webSite"] = @"https://www.blockchyp.com"; + request[@"taxIdNumber"] = @"123456789"; + request[@"entityType"] = @"CORPORATION"; + request[@"stateOfIncorporation"] = @"UT"; + request[@"merchantType"] = @"RETAIL"; + request[@"businessDescription"] = @"Payment processing solutions"; + request[@"yearsInBusiness"] = @"5"; + request[@"businessPhoneNumber"] = @"5555551234"; + NSMutableDictionary *physicaladdress = [[NSMutableDictionary alloc] init]; + physicaladdress[@"address1"] = @"355 S 520 W"; + physicaladdress[@"city"] = @"Lindon"; + physicaladdress[@"stateOrProvince"] = @"UT"; + physicaladdress[@"postalCode"] = @"84042"; + physicaladdress[@"countryCode"] = @"US"; + request[@"physicalAddress"] = physicaladdress; + NSMutableDictionary *mailingaddress = [[NSMutableDictionary alloc] init]; + mailingaddress[@"address1"] = @"355 S 520 W"; + mailingaddress[@"city"] = @"Lindon"; + mailingaddress[@"stateOrProvince"] = @"UT"; + mailingaddress[@"postalCode"] = @"84042"; + mailingaddress[@"countryCode"] = @"US"; + request[@"mailingAddress"] = mailingaddress; + request[@"contactFirstName"] = @"John"; + request[@"contactLastName"] = @"Doe"; + request[@"contactPhoneNumber"] = @"5555555678"; + request[@"contactEmail"] = @"john.doe@example.com"; + request[@"contactTitle"] = @"CEO"; + request[@"contactTaxIdNumber"] = @"987654321"; + request[@"contactDOB"] = @"1980-01-01"; + request[@"contactDlNumber"] = @"D1234567"; + request[@"contactDlStateOrProvince"] = @"NY"; + request[@"contactDlExpiration"] = @"2025-12-31"; + NSMutableDictionary *contacthomeaddress = [[NSMutableDictionary alloc] init]; + contacthomeaddress[@"address1"] = @"355 S 520 W"; + contacthomeaddress[@"city"] = @"Lindon"; + contacthomeaddress[@"stateOrProvince"] = @"UT"; + contacthomeaddress[@"postalCode"] = @"84042"; + contacthomeaddress[@"countryCode"] = @"US"; + request[@"contactHomeAddress"] = contacthomeaddress; + request[@"contactRole"] = @"OWNER"; + NSMutableArray *owners = [[NSMutableArray alloc] init]; +NSMutableDictionary *owners1 = [[NSMutableDictionary alloc] init]; +owners1[@"firstName"] = @"John"; +owners1[@"lastName"] = @"Doe"; +owners1[@"jobTitle"] = @"CEO"; +owners1[@"taxIdNumber"] = @"876543210"; +owners1[@"phoneNumber"] = @"5555559876"; +owners1[@"dob"] = @"1981-02-02"; +owners1[@"ownership"] = @"50"; +owners1[@"email"] = @"john.doe@example.com"; +owners1[@"dlNumber"] = @"D7654321"; +owners1[@"dlStateOrProvince"] = @"UT"; +owners1[@"dlExpiration"] = @"2024-12-31"; +NSMutableDictionary *address = [[NSMutableDictionary alloc] init]; + address[@"address1"] = @"355 S 520 W"; + address[@"city"] = @"Lindon"; + address[@"stateOrProvince"] = @"UT"; + address[@"postalCode"] = @"84042"; + address[@"countryCode"] = @"US"; + owners1[@"address"] = address; +[owners addObject:owners1]; + request[@"owners"] = owners; + NSMutableDictionary *manualaccount = [[NSMutableDictionary alloc] init]; + manualaccount[@"name"] = @"Business Checking"; + manualaccount[@"bank"] = @"Test Bank"; + manualaccount[@"accountHolderName"] = @"BlockChyp Inc."; + manualaccount[@"routingNumber"] = @"124001545"; + manualaccount[@"accountNumber"] = @"987654321"; + request[@"manualAccount"] = manualaccount; + request[@"averageTransaction"] = @"100.00"; + request[@"highTransaction"] = @"1000.00"; + request[@"averageMonth"] = @"10000.00"; + request[@"highMonth"] = @"20000.00"; + request[@"refundPolicy"] = @"30_DAYS"; + request[@"refundDays"] = @"30"; + request[@"timeZone"] = @"America/Denver"; + request[@"batchCloseTime"] = @"23:59"; + request[@"multipleLocations"] = @"false"; + request[@"ebtRequested"] = @"false"; + request[@"ecommerce"] = @"true"; + request[@"cardPresentPercentage"] = @"70"; + request[@"phoneOrderPercentage"] = @"10"; + request[@"ecomPercentage"] = @"20"; + request[@"signerName"] = @"John Doe"; + + [client submitApplicationWithRequest:request handler:^(NSDictionary *request, NSDictionary *response, NSError *error) { + + [self logJSON:response]; + XCTAssertNotNil(response); + // response assertions + XCTAssertTrue([[response objectForKey:@"success"]boolValue]); + + [expectation fulfill]; + }]; + + @try { + [self waitForExpectationsWithTimeout:60 handler:nil]; + } + @catch (NSException *exception) { + NSLog(@"Exception:%@",exception); + } + +} + +@end