Got questions? Connect with our experts on Vantiv ONE.
This is a resource for developers and interested payment integrators to see how simple it is to get your iOS POS to integrate with Mercury StoreCard.
iOS Simulator Note: QR Code will not scan without building on an actual iPad device. If iOS simulating please make sure you use iPad2
##Step 1: Build Request with Key Value Pairs
Create a NSMutableDictionary and add all the Key Value Pairs.
NSMutableDictionary *dictionary = [NSMutableDictionary new];
[dictionary setObject:num forKey:@"InvoiceNo"]; //randoNum to avoid AP*
[dictionary setObject:num forKey:@"RefNo"]; //randoNum to avoid AP*
[dictionary setObject:@"StoreCard iOS Demo POS" forKey:@"Memo"];
[dictionary setObject:[NSString stringWithFormat:@"%.2f", _total] forKey:@"Purchase"];
[dictionary setObject:acct forKey:@"AcctNo"];
[dictionary setObject:@"6453 Bistro iOS App" forKey:@"OperatorID"];
[dictionary setObject:@"Bistro 6435 iOS Demo POS - StoreCard" forKey:@"Memo"];
[self processTransactionWithDictionary:dictionary andResource:@"/PrePaid/Sale"];
##Step 1b: Add your choice of an image scanning SDK or use AVFoundation
- (IBAction)startStopReading:(id)sender;
- (IBAction)startStopReading:(id)sender {
if (!_isReading) {
// This is the case where the app should read a QR code when the start button is tapped.
if ([self startReading]) {
// If the startReading methods returns YES and the capture session is successfully
// running, then change the start button title and the status message.
}
}
else{
// In this case the app is currently reading a QR code and it should stop doing so.
[self stopReading];
}
// Set to the flag the exact opposite value of the one that currently has.
_isReading = !_isReading;
}
#pragma mark - Private method implementation
- (BOOL)startReading {
NSError *error;
// Get an instance of the AVCaptureDevice class to initialize a device object and provide the video
// as the media type parameter.
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// Get an instance of the AVCaptureDeviceInput class using the previous device object.
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
// If any error occurs, simply log the description of it and don't continue any more.
NSLog(@"%@", [error localizedDescription]);
return NO;
}
// Initialize the captureSession object.
_captureSession = [[AVCaptureSession alloc] init];
// Set the input device on the capture session.
[_captureSession addInput:input];
// Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[_captureSession addOutput:captureMetadataOutput];
// Create a new serial dispatch queue.
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("myQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
[captureMetadataOutput setMetadataObjectTypes:[NSArray arrayWithObject:AVMetadataObjectTypeQRCode]];
// Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
[_viewPreview.layer addSublayer:_videoPreviewLayer];
// Start video capture.
[_captureSession startRunning];
return YES;
}
-(void)stopReading {
// Stop video capture and make the capture session object nil.
[_captureSession stopRunning];
_captureSession = nil;
// Remove the video preview layer from the viewPreview view's layer.
[_videoPreviewLayer removeFromSuperlayer];
}
#pragma mark - AVCaptureMetadataOutputObjectsDelegate method implementation
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
// Check if the metadataObjects array is not nil and it contains at least one object.
if (metadataObjects != nil && [metadataObjects count] > 0) {
// Get the metadata object.
AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) {
// If the found metadata is equal to the QR code metadata then update the status label's text,
// stop reading and change the bar button item's title and the flag's value.
// Everything is done on the main thread.
[self performSelectorOnMainThread:@selector(sendTransaction:) withObject:[metadataObj stringValue] waitUntilDone:NO];
[self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
_isReading = NO;
}
}
}
##Step 2: Process the Transaction
Process the transaction with an NSMutableURLRequest.
// Create a JSON POST
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
// Add Authorization header
NSString *credentials = [NSString stringWithFormat:@"%@:%@", self.merchantID, self.merchantPassword];
NSString *base64Credentials = [self base64String:credentials];
[request addValue:[@"Basic " stringByAppendingString:base64Credentials] forHTTPHeaderField:@"Authorization"];
// Serialize NSDictionary to JSON data
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];
// Add JSON data to request body
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[jsonData length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody: jsonData];
// Process request async
[NSURLConnection connectionWithRequest:request delegate:self];
##Step 3: Parse the Response
Parse the Response using in the connection didReceiveData delegate.
Approved transactions will have a CmdStatus equal to "Approved".
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Deserialize response from REST service
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if ([result objectForKey:@"CmdStatus"]
&& [[result objectForKey:@"CmdStatus"] isEqualToString:@"Approved"]) {
// Approved logic here
} else {
// Declined logic here
}
}
Contact a Developer Integration Analyst on the Mercury Developer Portal for more information.
###© 2015 Mercury Payment Systems, LLC - all rights reserved.
Disclaimer: This software and all specifications and documentation contained herein or provided to you hereunder (the "Software") are provided free of charge strictly on an "AS IS" basis. No representations or warranties are expressed or implied, including, but not limited to, warranties of suitability, quality, merchantability, or fitness for a particular purpose (irrespective of any course of dealing, custom or usage of trade), and all such warranties are expressly and specifically disclaimed. Mercury Payment Systems shall have no liability or responsibility to you nor any other person or entity with respect to any liability, loss, or damage, including lost profits whether foreseeable or not, or other obligation for any cause whatsoever, caused or alleged to be caused directly or indirectly by the Software. Use of the Software signifies agreement with this disclaimer notice.