Skip to main content

(Classic) How to use the Payment API


This article describes an integration with the v1 of the API. Ongoing development on this version has stopped. Please use our new and improved API v2!

In this article we present a few hands-on examples of how to use the FinDock Payment API. 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. 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 FinDock introduction article. For more examples, please visit our payment extensions documentation.

New one-time payment#

Payments are initiated by performing a POST to the FinDock /Payment 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.

    "SuccessURL":"",    "FailureURL":"",    “Origin”:”Standard online payment form”,

The Payer object contains the details of the payer, in this example, Eric Johnson. 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. The ContactUpdate attribute indicates that if an existing contact is found, the Email, Firstname and Lastname fields of that existing contact should be updated to match the information provided in the request.

    "Payer":{            "Contact":{                "FirstName":"Eric",                "LastName":"Johnson",                "Email":"",                "MailingStreet":"Rocket Rd",                "MailingCity":"Hawthorne0",                "MailingPostalCode":"CA 90250",                "MobilePhone":"98989898"            },            "Account":{                "Name":"Johnson Family",                "Website":"",                "BillingStreet":"Rocket Rd",                "BillingCity":"Hawthorne",                "BillingPostalCode":"CA 90250"            },
            "AccountUpdate":"Replace",            "ContactUpdate":"Replace",            "AllowDeduplication":true,            "PrimaryRelation":"Contact"        },

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.

    "Payment":{            "Amount":10    },

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.

    "PaymentMethod":{            "Name":"CreditCard",            "Processor" :"PaymentHub-Mollie"    },

If no Processor is provided, FinDock uses the default payment processor configured for this payment method in the FinDock setup. To find out which Payment Processor is the default, perform a GET on the /PaymentMethods endpoint.

The SourceConnector object explicitly defines FinDock as the source. This means we are using FinDock Standalone there are no source apps, such as Nonprofit Success Pack, in the Salesforce org that would need the payment data.

    "SourceConnector":{            "Name":"PaymentHub"     },

The full message should look something like this:

    {        "SuccessURL":"",        "FailureURL":"",        "Payer":{            "Contact":{                "FirstName":"Eric",                "LastName":"Johnson",                "Email":"",                "MailingStreet":"Rocket Rd",                "MailingCity":"Hawthorne0",                "MailingPostalCode":"CA 90250",                "MobilePhone":"98989898"            },            "Account":{                "Name":"Johnson Family",                "Website":"",                "BillingStreet":"Rocket Rd",                "BillingCity":"Hawthorne",                "BillingPostalCode":"CA 90250"            },
            "AccountUpdate":"Replace",            "ContactUpdate":"Replace",            "AllowDeduplication":true,            "PrimaryRelation":"Contact"        },        "Payment":{            "Amount":10        },        "PaymentMethod":{            "Name":"CreditCard",        "Processor" :"PaymentHub-Mollie"
        },        "SourceConnector":{            "Name":"PaymentHub"        }    }


The response on the new one-time payment request has a similar structure to the request:

    {        "ResponseCode": "001",        "IsSuccess": true,        "SourceConnector": {            "Name": "PaymentHub"        },        "RedirectURL": "https://myfindock-developer-edition.eu29.force.comapex/moph__redirect?",        "PaymentMethod": {            "Processor": "PaymentHub-Mollie",            "Name": "CreditCard"        },        "Payment": {            "InstallmentId": "a083X00001brH4pQAE"        },        "Payer": {            "ContactId": "0033X000032V8LHQA0",            "ContactDeduplicated": false,            "AccountId": "0013X00002bZPGIQA4",            "AccountDeduplicated": false        }    }

The Root of the response contains the response code 001 indicating that the request was processed successfully and as such sets IsSuccess to true.

The Payer object response indicates that the contact was not deduplicated and provides the ID of the Contact record that is now connected to the transaction. Since we also provided Account details, an Account has been created and linked to the Contact.

Payment API payer contact details

The Payment object response contains the InstallmentId that was created for the new transaction. This InstallmentId is the unique Salesforce record ID and can be used to query the status of the payment through the FinDock /Payment endpoint. The installment is also linked to the provided Contact because PrimaryRelation was set to ‘Contact’ in the request.

Payment API payment installment details

The PaymentMethod object response indicates that the transaction was processed as a credit card payment through Mollie.

The SourceConnector object response indicates that the Salesforce data was created through PaymentHub (FinDock standalone).

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.

    "RedirectURL": "https://myfindock-developer-edition.eu29.force.comapex/moph__redirect?"

In our example, since Mollie is the processor, the payment form is a Mollie payment form.


Most payment processors show different pages for testing. In this case, the status of the payment can be changed without entering any credit card details. 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.

Payment API PSP test profile

Once the customer completes the transaction, FinDock receives a callback from the PSP (Mollie) and the following occurs:

  • The customer is redirected to either the SuccessURL or FailureURL indicated in the request based on whether the transaction was completed successfully or cancelled.
  • The installment record is updated (status is set to ‘Collected’ and amount is reduced by the amount paid to 0).
    Payment API_payment_installment_collected
  • A Payment record is created for the Installment.
    Payment API_payment_installment_payment record
  • 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.
    Payment API_payment_profile

Pay existing installment#

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 with one important exception: an InstallmentId is added in the Payment object. This replaces the Payer object, since this customer data is already in Salesforce. A basic request looks something like this:

    {        "SuccessURL":"",        "FailureURL":"",
        "Payment":{            "InstallmentId": "a083X00001brHFCQA2",            "Amount": 10        },        "PaymentMethod":{            "Name": "CreditCard",            "Processor": "PaymentHub-Mollie"
        },        "SourceConnector":{            "Name":"PaymentHub"        }    }


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.

    {        "ResponseCode": "001",        "IsSuccess": true,        "SourceConnector": {            "Name": "Mollie for PaymentHub"        },        "RedirectURL": "",        "PaymentMethod": {            "Processor": "PaymentHub-Mollie",            "Name": "CreditCard"        },        "Payment": {            "InstallmentId": "a083X00001brHFCQA2"        },        "Payer": {          "ContactDeduplicated": false,            "AccountDeduplicated": false        }    }

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).

    "Recurring": {          "Amount": "25",          "Frequency": "Monthly",          "StartDate": "2020-04-01"     }


In the response, you get a Recurring object with a Salesforce ID of the Recurring Payment object that has been created in Salesforce.

    "Recurring": {            "RecurringId": "a0V3X00000PEwFbUAL"        }

Payment API recurring payment

Related to the Recurring Payment, you can find the first Installment that was created through the API request.