Add a Debit Card
Overview
You can provide the ability for workers to have payments made to an existing debit card, instead of the Branch Wallet, by embedding the Branch-customized TabaPay SSO Card Widget. This will let a worker securely input card details, returning a token to access the card data in a PCI-compliant manner.
Implementation
Prerequisites
- Ensure security when adding a debit card by having workers login using Multi-Factor Authentication
- Develop a new endpoint called
AddDebitCard
for your backend server- Accept a
POST
request containing the worker's details (see step 5 for example request) - Forward the worker's details to Branch's Add External Card endpoint
- Save the returned External Card's
ID
to the company database, to be used for future API calls
- Accept a
JavaScript Web Implementation
- Add HTML to contain the Card Widget iFrame:
<div><iframe id="card-widget"></iframe></div>
- Add JavaScript to load the Card Widget into the iFrame
- Production URL: https://direct-embed.branchapp.com/card-widget.html
- Sandbox URL: https://direct-embed-sandbox.branchapp.com/card-widget.html
// The URL below is for the Branch Sandbox, choose the production or sandbox URL accordingly
var iFrameURL = "https://direct-embed-sandbox.branchapp.com/card-widget.html";
document.getElementById("card-widget").src = iFrameURL;
- Create a JavaScript function to extract the Card Widget iFrame data upon completion and forward them to your backend server endpoint
function extractCardWidgetData( event ) {
if ( event.data != "Close" ) {
if ( event.data.slice( 0, 7 ) == "Error: " ) {
// Error
} else {
var asData = event.data.split( "|" );
if ( asData.length == 9 ) {
// asData[ 0 ] contains the First Name
// asData[ 1 ] contains the Last Name
// asData[ 2 ] contains the Card BIN+Last4
// asData[ 3 ] contains the expiration in YYYYMM format
// asData[ 4 ] contains the token
// asData[ 5 ] contains the address
// asData[ 6 ] contains the city
// asData[ 7 ] contains the state 2 char ISO code
// asData[ 8 ] contains the zip code
const firstName = asData[0]; // "John"
const lastName = asData[1]; // "Larson"
const cardBinAndLast4 = asData[2]; // "4111111111"
const expiration = asData[3]; // "202605"
const token = asData[4]; // "80BLD07rSYbG6u..."
const address = asData[5]; // "1234 Any Street"
const city = asData[6]; // "Kalispell"
const state = asData[7]; // "MT"
const zipCode = asData[8]; // "59901"
// Forward the extracted worker details to your backend server endpoint
fetch("https://www.your-backend-server.com/add-debit-card", {
method: "POST",
body: JSON.stringify({
firstName: firstName,
lastName: lastName,
cardBinAndLast4: cardBinAndLast4,
expiration: expiration,
token: token,
address: address,
city: city,
state: state,
zipCode: zipCode
}),
headers: {
"Content-type": "application/json; charset=UTF-8"
}
});
} else {
// Data Error
}
}
} else {
// Close or Cancel
}
}
- Use JavaScript to bind the data extraction function to a listener on the Card Widget iFrame completion event
window.addEventListener( "message", extractCardWidgetData, false );
Swift iOS Implementation
import UIKit
import WebKit
class ViewController: UIViewController {
// The URL below is for the Branch Sandbox, choose the production or sandbox URL accordingly
let cardWidgetURL = URL(string: "https://direct-embed-sandbox.branchapp.com/card-widget.html")!
lazy var webView: WKWebView = {
let contentController = WKUserContentController()
contentController.add(self, name: "ios")
let jsScript = """
window.addEventListener("message", (event) => {
window.webkit.messageHandlers.ios.postMessage(event.data);
}, false);
"""
let userScript = WKUserScript(source: jsScript, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(userScript)
let config = WKWebViewConfiguration()
config.userContentController = contentController
let webView = WKWebView(frame: self.view.bounds, configuration: config)
webView.load(URLRequest(url: cardWidgetURL))
return webView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(webView)
}
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let messageBody = message.body as? String else { return }
if messageBody == "Close" {
// Close or cancel
} else if messageBody.starts(with: "Error: ") {
// Error
} else {
let data = messageBody.split(separator: "|")
if data.count == 9 {
let cardData = [
"firstName": data[0], // "John"
"lastName": data[1], // "Larson"
"cardNumber": data[2], // "4111111111"
"expiration": data[3], // "202605"
"token": data[4], // "80BLD07rSYbG6u..."
"address": data[5], // "1234 Any Street"
"city": data[6], // "Kalispell"
"state": data[7], // "MT"
"zipCode": data[8] // "59901"
]
// Send data to your backend server
} else {
// Invalid data format
}
}
}
}
Testing Cards
- Enter sample card numbers from here to test the functionality of
extractCardWidgetData
- Card type must be debit for a successful response
- Using a CVV of 999 will generate an invalid CVV response
Example Card Widget iFrame - Sandbox
Updated 14 days ago