Table of Contents
Overview
This article gives a brief overview of how to convert a digitally captured signature in Bitmap format into the base64 encoded string required by the Payment Device SDK. Please note that this article already assumes you have the facility to capture a signature on the terminal.
Please note that Payment Device SDK versions 2.11 and onward change the way digital signature capture is performed and can be referenced at the bottom of the article here.
Android
Handling Signature Verification Callbacks
Payment Device SDK for Android handles signature request callbacks within the onSignatureVerification(Parameters) method, which should be supplied as an override. When a presented card requests signature entry as a form of CVM this callback will be fired. Please note that some devices have the capability to support on-device signature entry, and as such, a check should be performed to ascertain if the Payment Device SDK is required to process the signature entry.
Example:
@Override public void onSignatureVerification(Parameters parameters) { // Handle signature verification callback // Check if a response is required if (parameters.getValue(ParameterKeys.ResponseRequired).equals(ParameterValues.FALSE)) { // Signature handled on PINpad. No call to Payment Device SDK required return; } }
Checking If the Operator Pin Is Required
Before continuing with signature verification you should always check to ascertain if the Operator PIN is required. This is a unique value per terminal, and if required, should be provided within the OperatorPin ParameterSet when submitting the final signature to our platform.
Example:
// Check whether the Operator PIN is required final boolean operatorPinRequired = parameters.getValue(ParameterKeys.OperatorPinRequired).equals(ParameterValues.TRUE); /* Prompt for Operator PIN if required Assumed Operator PIN is returned in variable OperatorPin in this example */
Checking If Digital Signature Capture Is Supported
At this stage, if the integration does not support digital signature capture, you would expect the signature to be given physically and verified by the operator. As this article expects the signature to be entered digitally, we need to check if this is enabled by the platform.
Example:
// Check whether digital signature capture is enabled/supported if (parameters.getValue(ParameterKeys.DigitalSignatureSupported).equals(ParameterValues.TRUE) { /* Prompt for digital signature entry if supported and return a Bitmap image Assumed the Bitmap formatted signature is returned in variable CapturedSignature in this example */ }
Converting a Digitally Captured Signature into base64
Once a digital signature has been captured and returned to the integration as a Bitmap format, you should convert said image into a Base64 string supported by the Payment Device SDK. The signature will have whitespace trimmed to the edges of the final signature, which must be a minimum final dimension of either 150x25 or 25x150 pixels.
Example:
// Create a ByteArrayOutputStream and compress the captured signature into the stream ByteArrayOutputStream baos = new ByteArrayOutputStream(); CapturedSignature.compress(Bitmap.CompressFormat.PNG,100,baos); final String Base64EncodedSignature = encodeToString(baos.toByteArray(),DEFAULT);
Attaching the base64 Converted Signature into the Request
Now that you have all of the various components required to continue with signature verification you'll need to create a ParameterSet object, assign the relevant parameters required, and pass the finalized ParameterSet into the Payment Device SDK's continueSignatureVerification method. Ensure you log any potential errors returned from the response back to the integration.
Example:
// Create a ParameterSet, populate the required parameters, and call the Payment Device SDK's signature verification continuation method Parameters approveSignatureParameters = new Parameters(); approveSignatureParameters.add(ParameterKeys.Result, ParameterValues.TRUE); approveSignatureParameters.add(ParameterKeys.SignatureData, Base64EncodedSignature); if ( operatorPinRequired ) { approveSignatureParameters.add(ParameterKeys.OperatorPin, OperatorPin); } // Log and handle any errors that occur back to the integration Parameters response = ChipDnaMobile.getInstance().continueSignatureVerification(approveSignatureParameters); if (!response.containsKey(ParameterKeys.Result) || response.getValue(ParameterKeys.Result).equals(ParameterValues.FALSE)) { if (response.containsKey(ParameterKeys.Error)) { Log.d("Error:" + response.getValue(ParameterKeys.Error)); } }
Putting It All Together
Once all of the parts have been combined together, you should expect the full request to look like the below:
@Override public void onSignatureVerification(Parameters parameters) { // Handle signature verification callback // Check if a response is required if (parameters.getValue(ParameterKeys.ResponseRequired).equals(ParameterValues.FALSE)) { // Signature handled on PINpad. No call to Payment Device SDK required return; } // Check whether the Operator PIN is required final boolean operatorPinRequired = parameters.getValue(ParameterKeys.OperatorPinRequired).equals(ParameterValues.TRUE); /* Prompt for Operator PIN if required Assumed Operator PIN is returned in variable OperatorPin in this example */ // Check whether digital signature capture is enabled/supported if (parameters.getValue(ParameterKeys.DigitalSignatureSupported).equals(ParameterValues.TRUE) { /* Prompt for digital signature entry if supported and return a Bitmap image Assumed the Bitmap formatted signature is returned in variable CapturedSignature in this example */ // Create a ByteArrayOutputStream and compress the captured signature into the stream ByteArrayOutputStream baos = new ByteArrayOutputStream(); CapturedSignature.compress(Bitmap.CompressFormat.PNG,100,baos); final String Base64EncodedSignature = encodeToString(baos.toByteArray(),DEFAULT); // Create a ParameterSet, populate the required parameters, and call the Payment Device SDK's signature verification continuation method Parameters approveSignatureParameters = new Parameters(); approveSignatureParameters.add(ParameterKeys.Result, ParameterValues.TRUE); approveSignatureParameters.add(ParameterKeys.SignatureData, Base64EncodedSignature); if ( operatorPinRequired ) { approveSignatureParameters.add(ParameterKeys.OperatorPin, OperatorPin); } // Log and handle any errors that occur back to the integration Parameters response = ChipDnaMobile.getInstance().continueSignatureVerification(approveSignatureParameters); if (!response.containsKey(ParameterKeys.Result) || response.getValue(ParameterKeys.Result).equals(ParameterValues.FALSE)) { if (response.containsKey(ParameterKeys.Error)) { Log.d("Error:" + response.getValue(ParameterKeys.Error)); } } } }
iOS
Handling Signature Verification Callbacks
Payment Device SDK for iOS handles signature request callbacks within the registered method which we recommend defining during ViewDidLoad. When a presented card requests signature entry as a form of CVM this callback will be fired. Please note that some devices have the capability to support on-device signature entry, and as such, a check should be performed to ascertain if the Payment Device SDK is required to process the signature entry.
Example:
[ChipDnaMobile addSignatureVerificationTarget:self action:@selector(verifySignature:)];
-(void)verifySignature:(CCParameters *)request{ // Handle signature verification callback // Check if a response is required if ([[request valueForKey:CCParamResponseRequired] isEqualToString:CCValueFalse]) { // Signature handled on PINpad. No call to Payment Device SDK Mobile required return; } }
Checking If the Operator Pin Is Required
Before continuing with signature verification you should always check to ascertain if the Operator PIN is required. This is a unique value per terminal, and if required, should be provided within the OperatorPin ParameterSet when submitting the final signature to our platform.
Example:
// Check whether the Operator PIN is required BOOL operatorPinRequired = [[request valueForKey:CCParamOperatorPinRequired] isEqualToString:CCValueTrue]; /* Prompt for Operator PIN if required Assumed Operator PIN is returned in variable OperatorPIN in this example */
Checking If Digital Signature Capture Is Supported
At this stage, if the integration does not support digital signature capture, you would expect the signature to be given physically and verified by the operator. As this article expects the signature to be entered digitally, we need to check if this is enabled by the platform.
Example:
// Check whether digital signature capture is enabled/supported if ([[request valueForKey:CCParamDigitalSignatureSupported] isEqualToString:CCValueTrue]) { /* Prompt for digital signature entry if supported and return a UIImage object Assumed the UIImage formatted signature is returned in variable CapturedSignature in this example */ }
Converting a Digitally Captured Signature into base64
Once a digital signature has been captured and returned to the integration as a Bitmap format, you should convert said image into a Base64 string supported by the Payment Device SDK. The signature will have whitespace trimmed to the edges of the final signature, which must be a minimum final dimension of either 150x25 or 25x150 pixels.
Example:
// Convert the image into a Base64 encoded string NSString *base64EncodedImage = [UIImagePNGRepresentation(CapturedSignature) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
Attaching the base64 Converted Signature into the Request
Now that you have all of the various components required to continue with signature verification you'll need to create a ParameterSet object, assign the relevant parameters required, and pass the finalized ParameterSet into the Payment Device SDKs continueSignatureVerification method. Ensure you log any potential errors returned from the response back to the integration.
Example:
// Create a ParameterSet, populate the required parameters, and call the Payment Device SDK's signature verification continuation method CCParameters *approveSignatureParameters = [[CCParameters alloc] init]; [approveSignatureParameters setValue:CCValueTrue forKey:CCParamResult]; [approveSignatureParameters setValue:base64EncodedImage forKey:CCParamSignatureData]; if (operatorPinRequired) { [approveSignatureParameters setValue:OperatorPIN forKey:CCParamOperatorPin]; } // Log and handle any errors that occur back to the integration CCParameters *response = [[ChipDnaMobile sharedInstance] continueSignatureVerification:approveSignatureParameters]; if([[response valueForKey:CCParamResult] isEqualToString:CCValueFalse]){ [self log:[NSString stringWithFormat:@"Error: %@", [response valueForKey:CCParamError]]]; }
Putting It Back Together
Once all of the parts have been combined together, you should expect the full request to look like the below:
-(void)verifySignature:(CCParameters *)request{ // Handle signature verification callback // Check if a response is required if ([[request valueForKey:CCParamResponseRequired] isEqualToString:CCValueFalse]) { // Signature handled on PINpad. No call to Payment Device SDK Mobile required return; } // Check whether the Operator PIN is required BOOL operatorPinRequired = [[request valueForKey:CCParamOperatorPinRequired] isEqualToString:CCValueTrue]; /* Prompt for Operator PIN if required Assumed Operator PIN is returned in variable OperatorPIN in this example */ // Check whether digital signature capture is enabled/supported if ([[request valueForKey:CCParamDigitalSignatureSupported] isEqualToString:CCValueTrue]) { /* Prompt for digital signature entry if supported and return a UIImage object Assumed the UIImage formatted signature is returned in variable CapturedSignature in this example */ // Convert the image into a Base64 encoded string NSString *base64EncodedImage = [UIImagePNGRepresentation(CapturedSignature) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; // Create a ParameterSet, populate the required parameters, and call the Payment Device SDK's signature verification continuation method CCParameters *approveSignatureParameters = [[CCParameters alloc] init]; [approveSignatureParameters setValue:CCValueTrue forKey:CCParamResult]; [approveSignatureParameters setValue:base64EncodedImage forKey:CCParamSignatureData]; if (operatorPinRequired) { [approveSignatureParameters setValue:OperatorPIN forKey:CCParamOperatorPin]; } // Log and handle any errors that occur back to the integration CCParameters *response = [[ChipDnaMobile sharedInstance] continueSignatureVerification:approveSignatureParameters]; if([[response valueForKey:CCParamResult] isEqualToString:CCValueFalse]){ [self log:[NSString stringWithFormat:@"Error: %@", [response valueForKey:CCParamError]]]; } } }</pre
Payment Device SDK 2.11+
Payment Device SDK versions 2.11 and onward modify the way in which digital signature capture is performed, in which a bespoke listener is now utilized to prompt for digital signature capture. Once the signature data has been obtained it should be passed into the continueSignatureCapture(Parameters)
method, which in turn will trigger signature verification.
Please note that the card should not be removed during signature capture otherwise the transaction will immediately terminate. The card can be removed at any point after signature verification is prompted to allow the operator to confirm the customer's signature.