Important Note: This post deals with server-side transaction processing. Always make sure your server is up to the latest PCI server security compliance standards.
I'll briefly go over adding customers and recurring payment subscriptions in Coldfusion using Java. The basic documentation for Customers can be found at:
https://developers.braintreepayments.com/guides/customers/java
The following objects, including those previously mentioned in earlier posts, are required.
<!--- DECLARE JAVA OBJECTS --->
<cfobject type="java" class="com.braintreegateway.Environment" name="environment" />
<cfobject type="java" class="com.braintreegateway.CustomerRequest" name="customerReq" />
<cfobject type="java" class="com.braintreegateway.PaymentMethodRequest" name="paymentMethod" />
<cfobject type="java" class="com.braintreegateway.SubscriptionRequest" name="subscriptionRequest" />
<cfobject type="java" class="com.braintreegateway.BraintreeGateway" name="gateway" />
The following example shows how to add a customer to the Braintree Vault with a credit card:
<!--- MERCHANT INFO --->
<cfset variables.BTMerchantID = "1q2w3e4r" />
<cfset variables.BTPuclicKey = "0p9o8i7u" />
<cfset variables.BTPrivateKey = "5g6h7j8k" />
<!--- CUSTOMER DATA --->
<cfset variables.firstName = "Gerry" />
<cfset variables.lastName = "Mandering" />
<cfset variables.email = "gerrym@fakedomain.com" />
<cfset variables.phone = "843-555-4444" />
<cfset variables.planType = "Better" />
<!--- CARD DATA --->
<cfset variables.tempID = CreateUUID() />
<cfset variables.tAmount = 0.11 />
<cfset variables.tCC = 4111111111111111 />
<cfset variables.tExp = "09/2020" />
<cfset variables.tCVV = 400 />
<cfset variables.tbillAddr = "1234 Wallaby Way" />
<cfset variables.tPostalCode = 40000 />
<cfset variables.city = "Florence" />
<cfset variables.state = "SC" />
<!--- INITIALIZE MERCHANT GATEWAY --->
<cfset j = gateway.init(Environment.SANDBOX, '#variables.BTMerchantID#', '#variables.BTPublicKey#', '#variables.BTPrivateKey#')>
<!--- ADD CUSTOMER AND PAYMENT METHOD --->
<cfset variables.newCustomer = customerReq.firstName("#variables.firstName#").lastName("#variables.lastName#").email("#variables.email#").phone("#variables.phone#").creditCard().number('#variables.tCC#').expirationDate('#variables.tExp#').cvv('#variables.tCVV#').billingAddress().postalCode("#variables.tPostalCode#").streetAddress("#variables.tbillAddr#").locality("#variables.city#").region("#variables.state#").done().done() />
<cfset variables.newCReq = gateway.customer().create(variables.newCustomer) />
A payment nonce is more secure, but there's no reasonable documentation from Braintree for credit card nonce generators. In this example, however, here's how to pass a nonce when creating the customer in the vault:
<!--- ADD CUSTOMER AND PAYMENT METHOD --->
<cfset variables.newCustomer = customerReq.firstName("#variables.firstName#").lastName("#variables.lastName#").email("#variables.email#").phone("#variables.phone#").paymentMethodNonce("#variables.payNonce#") />
For examples on getting a payment nonce with PayPal, visit the previous post at:
http://www.openshawltdpro.com/coblog.aspx?cb=8
Nonces for other payment methods including Apple Pay and Google Pay have similar processes, but different scripts. Luckily, Braintree has decent examples in their documentation and require client tokens similar to how they're generated in examples from the previous post.
Once a customer is created with a payment method, you can get it to return a payment token. This token may be used to attach a subscription. Please note that when a customer is added to the vault with a payment method, the method is saved as a default and can't be overridden when the customer is first added. Here's how to retrieve the payment token:
<!--- VERIFY CUSTOMER AND PAYMENT METHOD IS SUCCESSFULL --->
<cfif variables.newCReq.isSuccess()>
<cfset variables.custID = variables.newCReq.getTarget().getId() />
<cfset variables.payToken = variables.newCReq.getTarget().getPaymentMethods() />
<cfif ArrayIsDefined(variables.payToken,1)>
<cfset variables.payTokenID = variables.payToken[1].getToken() />
<cfelse>
Payment Method Failed.
<cfabort/>
</cfif>
Success, BT Customer ID: <cfoutput>#variables.custID# <br/>
Payment Token: #variables.payTokenID#<br/>
</cfoutput>
<cfelse>
Unable to create customer account.
</cfif>
This method looks at all payment methods and grabs the first. Another process can be used to get the default by substituting getPaymentMethods() with getDefaultPaymentMethod(), which should only return only one value so an array lookup isn't needed. The default payment token can only be removed from default status when another payment method is added. Here's a basic example of adding a credit card to a customer account along with the object required to add the credit card request:
<!--- CC OBJECT --->
<cfobject type="java" class="com.braintreegateway.CreditCard" name="ccReq" />
<cfset variables.addCreditCard = ccreq().customerId("#variables.custID#").cvv("#variables.tCVV#").number("#variables.tCC#").expirationDate("#variables.tExp#") />
<cfset variables.addCC = gateway.creditCard().create(variables.addCreditCard) />
Adding a subscription is very simple once you have the subscription ID and payment token provided. The Braintree Control Panel is the best place to add subscriptions, set up recurring payments, and can get a subscription ID. The final example shows adding a subscription to the customer's account in Coldfusion.
<!--- ADD MEMBERSHIP SUBSCRIPTION --->
<cfif variables.planType IS "Good">
<cfset variables.planID = "453g" />
<cfelseif variables.planType IS "Better">
<cfset variables.planID = "dmp2" />
<cfelse>
<cfset variables.planID = "" />
</cfif>
<cfif Len(variables.planID)>
<!--- CREATE SUBSCRIPTION USING PLAN ID AND PAYMENT TOKEN ID --->
<cfset variables.setSubscription = subscriptionRequest.paymentMethodToken("#variables.payTokenID#").planId("#variables.planID#") />
<cfset variables.setSubResult = gateway.subscription().create(variables.setSubscription) />
<cfif variables.setSubResult.isSuccess()>
<cfset variables.getSubInfo = variables.setSubResult.getTarget().getId() />
Subscription ID: <cfoutput>#variables.getSubInfo#</cfoutput>
<cfelse>
Subscription Failed
</cfif>
</cfif>
That's about it. Feel free to try this code out in your sandbox account. Here's a complete example:
<!--- DECLARE JAVA OBJECTS --->
<cfobject type="java" class="com.braintreegateway.Environment" name="environment" />
<cfobject type="java" class="com.braintreegateway.CustomerRequest" name="customerReq" />
<cfobject type="java" class="com.braintreegateway.PaymentMethodRequest" name="paymentMethod" />
<cfobject type="java" class="com.braintreegateway.SubscriptionRequest" name="subscriptionRequest" />
<cfobject type="java" class="com.braintreegateway.BraintreeGateway" name="gateway" />
<!--- MERCHANT INFO --->
<cfset variables.BTMerchantID = "1q2w3e4r" />
<cfset variables.BTPuclicKey = "0p9o8i7u" />
<cfset variables.BTPrivateKey = "5g6h7j8k" />
<!--- CUSTOMER DATA --->
<cfset variables.firstName = "Gerry" />
<cfset variables.lastName = "Mandering" />
<cfset variables.email = "gerrym@fakedomain.com" />
<cfset variables.phone = "843-555-4444" />
<cfset variables.planType = "Better" />
<!--- CARD DATA --->
<cfset variables.tempID = CreateUUID() />
<cfset variables.tAmount = 0.11 />
<cfset variables.tCC = 4111111111111111 />
<cfset variables.tExp = "09/2020" />
<cfset variables.tCVV = 400 />
<cfset variables.tbillAddr = "1234 Wallaby Way" />
<cfset variables.tPostalCode = 40000 />
<cfset variables.city = "Florence" />
<cfset variables.state = "SC" />
<!--- INITIALIZE MERCHANT GATEWAY --->
<cfset j = gateway.init(Environment.SANDBOX, '#variables.BTMerchantID#', '#variables.BTPublicKey#', '#variables.BTPrivateKey#')>
<!--- ADD CUSTOMER AND PAYMENT METHOD --->
<cfset variables.newCustomer = customerReq.firstName("#variables.firstName#").lastName("#variables.lastName#").email("#variables.email#").phone("#variables.phone#").creditCard().number('#variables.tCC#').expirationDate('#variables.tExp#').cvv('#variables.tCVV#').billingAddress().postalCode("#variables.tPostalCode#").streetAddress("#variables.tbillAddr#").locality("#variables.city#").region("#variables.state#").done().done() />
<cfset variables.newCReq = gateway.customer().create(variables.newCustomer) />
<!--- VERIFY CUSTOMER AND PAYMENT METHOD IS SUCCESSFULL --->
<cfif variables.newCReq.isSuccess()>
<cfset variables.custID = variables.newCReq.getTarget().getId() />
<cfset variables.payToken = variables.newCReq.getTarget().getPaymentMethods() />
<cfif ArrayIsDefined(variables.payToken,1)>
<cfset variables.payTokenID = variables.payToken[1].getToken() />
<cfelse>
Payment Method Failed.
<cfabort/>
</cfif>
Success, BT Customer ID: <cfoutput>#variables.custID# <br/>
Payment Token: #variables.payTokenID#<br/>
</cfoutput>
<!--- ADD MEMBERSHIP SUBSCRIPTION --->
<cfif variables.planType IS "Good">
<cfset variables.planID = "453g" />
<cfelseif variables.planType IS "Better">
<cfset variables.planID = "dmp2" />
<cfelse>
<cfset variables.planID = "" />
</cfif>
<cfif Len(variables.planID)>
<!--- CREATE SUBSCRIPTION USING PLAN ID AND PAYMENT TOKEN ID --->
<cfset variables.setSubscription = subscriptionRequest.paymentMethodToken("#variables.payTokenID#").planId("#variables.planID#") />
<cfset variables.setSubResult = gateway.subscription().create(variables.setSubscription) />
<cfif variables.setSubResult.isSuccess()>
<cfset variables.getSubInfo = variables.setSubResult.getTarget().getId() />
Subscription ID: <cfoutput>#variables.getSubInfo#</cfoutput>
<cfelse>
Subscription Failed
</cfif>
</cfif>
<cfelse>
Unable to create customer account.
</cfif>