Hosted Card Payments Lightning Component
Available in: Salesforce Billing Winter ‘20 and later |
To use this component, you must also have Salesforce Billing installed in your org. For more information, see Install Salesforce Billing in Salesforce Help.
- The Expiration Month is required
- The Expiration Year is required
- The Email field is hidden
- The first address line has a label of "Street"
- The Pay Button's label has been changed to Save Card.
<force:CardPayment
paymentProvider = "{!v.paymentProvider}"
transactionType = "{!v.transactionType}"
transactionParams = "{!v.transactionParams}"
expiryMonthRequired = "true"
expiryYearRequired = "true"
hideEmail = "true"
addressLine1Label = "Street"
payButtonLabel="Save Card"/>
Once you’ve configured your component, you can embed it in a wrapper component that’s available in Experience Builder. Here’s a sample wrapper component with the cardPayment component embedded.
<aura:component>
<aura:handler name="paymentTransactionCompleted"
event="force:paymentTransactionCompleted"
action="{!c.handleTransactionResponse}"/>
<aura:attribute name="accountId" type="String" default="abcd"
description="Account to which the transaction details are related"/>
<aura:attribute name="gatewayId" type="String" default="1234"
description="Gateway to be used for the transaction"/>
<aura:attribute name="amount" type="Decimal" default="10"
description="amount to be charged for the transaction"/>
<aura:attribute name="paymentProvider" type="String" default='SalesforceBilling'
description="Payments provider for this component"/>
<aura:attribute name="transactionType" type="String" default='PaymentSale'
description="Transaction to be done after submitting the button"/>
<aura:attribute name="transactionParams" type="Object"
description="Contains details about account id and gateway id to use"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<force:cardPayment
paymentProvider = "{!v.paymentProvider}"
transactionType = "{!v.transactionType}"
transactionParams = "{!v.transactionParams}"
expiryMonthRequired = "true"
expiryYearRequired = "true"
hideEmail = "true"
addressLine1Label = "Street"
payButtonLabel="Save Card"/>
</aura:component>
handleTransactionResponse : function(cmp, event, helper) {
var response = event.getParam("response");
if(response.isSuccess) {
alert("isSuccess : " + response.isSuccess);
}
}
You can also add attributes to a design resource so that your admins have the option of hiding fields, making fields required, and changing labels. When your design resource is active, admins can select the payment component in Experience Builder to show a properties pane with checkboxes or text boxes for each of the attributes. Save your design resource as a .design file in the same directory as your wrapper component. For example, if you want to present your five customized attributes for your admins to select or deselect from the properties pane, add the following Design section.
<design:component>
<design:attribute name="expiryMonthRequired" label="Expiry month is required"/>
<design:attribute name="expiryYearRequired" label="Expiry year is required"/>
<design:attribute name="hideSaveForFuture" label="Hide save for future"/>
<design:attribute name="hideBillingAddressSection" label="Hide billing address section"/>
<design:attribute name="payButtonLabel" label="Pay button label"/>
</design:component>
Response Formats
- Success
-
During a successful response, isSuccess becomes true. If transactionType had a value of PaymentSale, salesforceResponse response contains paymentId, paymentMethodId, and paymentTransactionId. If transactionType had a value of SavePaymentCard, salesforceResponse contains only paymentMethodId. The attributes of gatewayResponse varies based on the gateway. This example shows a Success response for a PaymentSale transaction and all possible attributes for gatewayResponse.
{ "isSuccess" : true, "salesforceResponse" : { "paymentId" : "paymentId", "paymentMethodId" : "paymentMethodId", "paymentTransactionId" : "paymentTransactionId" }, "gatewayResponse": { "message": "mes", "responseCodeMessage": "rcm", "responseMessage": "rm", "responseCode": "rc", "responseStatus": "rs" } }
- Failure in the gateway
-
{ "isSuccess" : false, "salesforceResponse" : { "paymentTransactionId" : "paymentTransactionId" }, "gatewayResponse": { "message": "mes", "responseCodeMessage": "rcm", "responseMessage": "rm", "responseCode": "rc", "responseStatus": "rs" } }
- Failure Internally
-
{ "isSuccess": false, "errorDetails": { "message": "message" } }
Security Considerations and PCI Compliance
When end users are done entering their credit card information, they click the payment button so that the component sends the information to the payment gateway. Based on how you've configured your component, the gateway either tokenizes the card information and sends it back to the component, or the gateway tokenizes the card information, processes it for payment, and sends the results to the component.
Salesforce Billing uses security guardrails to ensure that end users aren’t charged more than once if they accidentally click the Pay Now button multiple times, or in the event of fraudulent activity. After the component sends a request to the payment gateway, it generates a nonce associated with that specific request. Salesforce Billing won't send another request unless the page is refreshed and the Hosted Card Payments component is re-rendered. The component validates the nonce before sending payment information to the gateway. If the nonce is valid, the component removes the nonce and sends the request to the gateway.
You can also use Javascript controllers to manage error handling and response handling. Here's a sample Javascript controller that uses the handler that we introduced earlier.
({
doInit : function(component, event, helper) {
var transactionParams = {};
transactionParams.accountId = component.get("v.accountId");
transactionParams.gatewayId = component.get("v.gatewayId");
transactionParams.amount = component.get("v.amount");
component.set("v.transactionParams", transactionParams);
},
handleTransactionResponse : function(cmp, event, helper) {
var response = event.getParam("response");
if(response.isSuccess) {
alert("isSuccess : " + response.isSuccess);
}
}
})