How can I store merchantIdentifier and merchantSecretKey without a backend?

If you don't have a backend, you can store the merchantIdentifier & merchantSecretKey locally on the device.

Option 1. Make it possible to set merchantIdentifier & merchantSecretKey in the settings

E.g., if you use the iOS Settings menu, you can use this in your settings bundle's plist:

<dict>
	<key>Title</key>
	<string>payment-group</string>
	<key>Type</key>
	<string>PSGroupSpecifier</string>
</dict>
<dict>
	<key>AutocapitalizationType</key>
	<string>None</string>
	<key>AutocorrectionType</key>
	<string>No</string>
	<key>DefaultValue</key>
	<string></string>
	<key>IsSecure</key>
	<false/>
	<key>Key</key>
	<string>payworks-merchantIdentifier</string>
	<key>KeyboardType</key>
	<string>Alphabet</string>
	<key>Title</key>
	<string>payworks-user</string>
	<key>Type</key>
	<string>PSTextFieldSpecifier</string>
</dict>
<dict>
	<key>AutocapitalizationType</key>
	<string>None</string>
	<key>AutocorrectionType</key>
	<string>No</string>
	<key>DefaultValue</key>
	<string></string>
	<key>IsSecure</key>
	<true/>
	<key>Key</key>
	<string>payworks-merchantSecretKey</string>
	<key>KeyboardType</key>
	<string>Alphabet</string>
	<key>Title</key>
	<string>payworks-password</string>
	<key>Type</key>
	<string>PSTextFieldSpecifier</string>
</dict>

Here are the strings:

"payment-group" = "Payment";
"payworks-user" = "payworks User";
"payworks-password" = "payworks Password";

Then, before you start the transaction, load the merchantIdentifier / merchantSecretKey:

NSString* merchantIdentifier = [[NSUserDefaults standardUserDefaults] stringForKey:@"payworks-merchantIdentifier"];
NSString* merchantSecretKey = [[NSUserDefaults standardUserDefaults] stringForKey:@"payworks-merchantSecretKey"];
    
if(merchantIdentifier == nil || [merchantIdentifier isEqualToString:@""] || merchantSecretKey == nil || [merchantSecretKey isEqualToString:@""]) {
    // credentials are not set! Instruct user how to get credentials
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Missing credentials"
                                                    message:@"Your username and/or password for using payment functionality is not set. Go to the settings and enter your username and password."
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
    return;
}

Make sure that an appropriate error message is shown if the credentials are not yet set. Tell the user how to get credentials and how to put them into the settings.

Option 2. Expose a URL scheme

To allow your merchant to configure the payment easily (without manually copying merchantIdentifier / merchantSecretKey), you can expose a URL scheme. This allows you to include a URL in emails to the merchant:

yourapp://payworks/configuration?payworks-username=<merchantIdentifier>&payworks-password=<merchantSecretKey>

First, register a URL scheme in your Info.plist:

<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleURLName</key>
		<string>io.payworks.config</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>yourapp</string>
		</array>
	</dict>
</array>

Then, in your AppDelegate, parse the URL and configure the settings:

- (NSDictionary *)parseQueryString:(NSString *)query {
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:6];
    NSArray *pairs = [query componentsSeparatedByString:@"&"];
    
    for (NSString *pair in pairs) {
        NSArray *elements = [pair componentsSeparatedByString:@"="];
        NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        
        [dict setObject:val forKey:key];
    }
    return dict;
}

- (void) showError {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Could not configure payment"
                                                    message:@"The link you clicked seems to be broken."
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
}

- (void) showSuccess {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Payment has been configured"
                                                    message:@"You can do transactions now!"
                                                   delegate:nil
                                          cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    [alert show];
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    // handler code here
    if([[url host] isEqualToString:@"payworks"] && [[url path] isEqualToString:@"/configuration"]) {
        NSDictionary *dict = [self parseQueryString:[url query]];
        if([dict objectForKey:@"payworks-username"] && [dict objectForKey:@"payworks-password"]) {
            NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
            [defaults setObject:[dict objectForKey:@"payworks-username"] forKey:@"payworks-merchantIdentifier"];
            [defaults setObject:[dict objectForKey:@"payworks-password"] forKey:@"payworks-merchantSecretKey"];
            [self showSuccess];
        } else {
            [self showError];
        }
    } else {
        [self showError];
    }

    return YES;
}

Can we help you?

If you cannot find your answer, contact us and we'll get in touch with you soon.