This article describes an integration with version 2 of the Payment API. If you are working on an existing API version 1 implementation, we strongly recommend you migrate to API v2. Please visit our migration article.
Enhanced Online Experience (with API v2) will be in Beta from the October '20 release onwards.
In this article we present a few hands-on examples of how to use the FinDock Payment API.
- To find out how our API works, please visit our How the Payment API works article.
- If you haven’t already, please check out Getting started with the Payment API before continuing.
- For detailed information about our API, please visit our API reference guide.
- To learn about and configure online reconciliation with Guided Matching, check our processing and reconciliation article,
- If you run into any issues, please visit our Troubleshooting the API article.
The examples here use credit card as the payment method and FinDock as the source. If these terms (method and source) are unfamiliar to you, please read our getting started article.
New one-time payment
Payments are initiated by performing a POST to the FinDock
endpoint. The request must have a body and an authorization header.
The Root of the request contains the success and failure URLs and the origin (e.g. what website or platform is making the request). The Root may also include a webhook URL, but this attribute is not required. If the transaction is successful, the customer is redirected to the success URL. If the customer cancels the transaction, the redirection is to the failure URL. The origin is logged in Salesforce as a text string to indicate what form was used for initiating the transaction.
The Payer object contains the details of the payer, Eric Johnson, in this example. AllowDepulication is set to true, so if Salesforce finds an existing Eric Johnson in the database (according to the deduplication rules), the existing contact shall be used.
Please note we put all the Contact and Account fields in a
SalesforceFields object. In this object, you can pass any field - both standard Salesforce and custom - that is available on this object in your Salesforce environment.
If you are using NPSP, we recommend adding AccountRecordTypeName to the Account declaration.
The Payment object indicates this request is a one-time transaction. The amount is 10, and since there is no CurrencyISOCode attributed, the default currency defined for the Salesforce org is used.
The PaymentMethod object indicates the transaction uses the credit card payment method. Since this Salesforce org has several processors configured that can be used to perform credit card payments, we explicitly specify Mollie as the processor.
If no processor is provided, FinDock uses the default payment processor configured for this payment method in the FinDock setup. To find out which processor is the default, perform a GET on the
The Settings object explicitly defines FinDock as the source. This means we are using FinDock Standalone and there are no source apps, such as Nonprofit Success Pack, in the Salesforce org that would need the payment data.
You can leave the
SourceConnector parameter out if you always want to use the default source connector in the Salesforce environment.
The full message sent to
https://your-org-url.force.com/services/apexrest/cpm/v2/PaymentIntent should look something like this:
The response on the new one-time payment request has a similar structure to the request:
The Settings object response indicates that the payment was created with FinDock Standalone (PaymentHub) as
The PaymentMethod object response indicates that the transaction will be processed as a Credit Card payment through Stripe.
The Id is an Id that identifies this Payment Intent. This id is stable across all communication from and to FinDock, and can be found:
- on the created Inbound Report record in Salesforce. On this Inbound Report the API call is processed through Guided Matching.
- in Webhook notifications to the
WebhookURLyou can specify in the request body.
You can also retrieve the status of the Payment through a
GET request on the
For more information on processing and reconciliation of online Payments through Guided Matching, please read our processing and reconciliation article.
Finalizing the one-time transaction
Because this is a new payment for a new contact, the customer/donor needs to provide credit card details and should be forwarded to the RedirectURL in the response.
In our example, since Stripe is the processor, the payment form is a Stripe payment form.
Although this Stripe payment page is close to the production version, many payment processors show different pages for testing. We strongly recommend performing a ‘penny test’ with a real, small payment amount in your production environment to account for these differences in the test setup.
Once the customer completes the transaction, the customer is redirected to the
FailureURL value from the initial
PaymentIntent. Parallely, FinDock receives a callback from
the PSP (Stripe) and the following actions are performed in Salesforce through Guided Matching:
- The installment record is updated (status is set to ‘Collected’ and amount is reduced by the amount paid to 0).
- A Payment record is created for the Installment.
- A Payment Profile is created related to the Contact based on the data provided by the PSP, like the type of credit card. If the Payment Profile had already existed for this contact, it would have been updated instead. This data can be used to personalize (e.g. pre-fill forms) future payment requests for this customer. Payment profiles are deduplicated automatically by FinDock.
Pay existing outstanding installment
Payments are initiated by performing a POST to the FinDock
/PaymentIntent endpoint. The request must have a body and an authorization header. Make sure the Installment you are trying to pay has an open amount.
The request body is the same as for a new one-time payment with one important exception: an InstallmentId is added in the OneTime object. No Payer object is required, since this customer data is already in Salesforce. A basic request looks something like this:
If additional actions are required from the customer, a redirectURL is returned in the response body. Once the transaction has been completed or cancelled, the PSP notifies FinDock through the callback, and FinDock updates the data in Salesforce accordingly.
New recurring payment
Payments are initiated by performing a POST to the FinDock /Payment endpoint. The request must have a body and an authorization header.
The request body is the same as for a new, one-time payment except that it uses a Recurring object that replaces the Payment object. Some PSPs require an ‘initial’ transaction for authentication. In those cases both a Payment and a Recurring object is passed. Whether such an authorization is required can be queried from the GET
/PaymentMethod and GET
/PaymentProcessors endpoints. For further information, see the relevant PSP articles under Payment Extensions.
The Recurring object defines the amount and frequency of the recurring transaction, as well as the start date (when the first transaction can be billed).
In the response, you get a similar response to a
OneTime request, with - in this case - a
RedirectURL to perform an authorization.
Related to the Recurring Payment, you can find:
- the first Installment that was created through the API request.
- the Mandate with data (in this case a Stripe Credit Card token) to collect further installments through the Payment Schedule.
- the Payment Profile with any Credit Card details that Stripe has returned.
Default Bank Statement Description field with Salesforce automation or by passing
cpm__Bank_Statement_Description__c in the
SalesforceFields in the
Recurring object in your API call, to show the Payer a friendly description on their bank statement.