# Troubleshooting the Payment API v2

When something goes wrong with a Payment API call, FinDock tries to help you with Response Codes and descriptive Error Messages. If the root cause cannot be determined, the API returns error code 999 with a generic error message.

## Error and Response Codes

If the API is not called successfully, you receive a HTTP Status Code `400` or `500`. The response includes additional information on how to prevent or handle the error through an array of `Errors` with an `error_code` and `error_message`, as in the example below.


```json
{
    "Errors": [
    {
        "error_message": "Amount can't be 0 or negative",
        "error_code": "200"
    }
    ]
}
```

For a full list of codes, see [Error and response codes](/api/payment-api-v2/section/error-and-response-codes).

## Common issues

The following sections describe the most common issues and resolutions.

### Authentication and permissions

Response codes [040], [999] can indicate an authentication issue or missing Salesforce permissions.

Example error message:


```json
    {
    "message": "Session expired or invalid",
    "errorCode": "INVALID_SESSION_ID"
    }
```

| Issue | Resolution |
|  --- | --- |
| Missing or expired bearer token | Setup authentication with the Salesforce org and pass the token in the Authorization header. Use `refresh_token` to retrieve a new `authentication_code`. |
| Missing permissions for integration user account for API calls | Confirm [general permissions](/docs/setup/general-permission-guidance) and [permission set groups](/docs/setup/permission-set-groups) are configured correctly. |
| Missing source-specific permissions for integration user account for API calls | Confirm permissions are correctly assigned for the given source, e.g. [NPSP](/docs/source-connectors/configuring-findock-for-npsp#install-npsp-source-connector) or [Fundraising](/docs/source-connectors/configuring-findock-for-fundraising#fundraising-minimum-configuration) |


### Payment data

Reason codes [010], [011], [012], [098], [200], and [999] point to missing or invalid data in API requests. These errors can be thrown by the Payment API or by processes in Salesforce like validation rules and Apex classes.

| Issue | Resolution |
|  --- | --- |
| "Contact error: Required fields are missing: [LastName]" or similar error | Even though the field is not required in the API, there might be logic set up in Salesforce that makes the field required on insert or update. Check your Salesforce configuration, e.g. validation rules, to see if the field is mandatory and adjust the request body accordingly. |
| "No Default Setup Record found for category PSP" or similar error [098] | API request is missing a required object. Make sure your request follows the [PaymentIntent schema](/api/payment-api-v2/payment-intent/paymentintent). Also ensure that defaults are configured as expected in the org for source and payment methods. |
| “Required Parameter "Contact" missing for section Payer" or similar error [010] | API request is missing Payer data. Make sure your request follows the [PaymentIntent schema](/api/payment-api-v2/payment-intent/paymentintent) and includes required Payer parameters. |


### Configuration issues

Reason codes [030] and [999] indicate missing or incorrect configuration in Salesforce and/or FinDock.

| Problem | Resolution |
|  --- | --- |
| "Page not found" or similar | When you create a site in Salesforce, it might look like an HTTP URL in the Salesforce Setup field. However, it reroutes to HTTPS. All API integrations need to use HTTPS in URLs. | |
| Unexpected redirect | PSP integration incorrectly configured. If the RedirectURL returned by the API results in an error or something expected, check the [processor configuration](/docs/payment-processors). **NOTE:** Specific errors like "Invalid Credit Card number" can also indicate a configuration problem rather than an issue with the credit card details. |
| Missing records or data updates in Salesforce | Ensure [WebHub is connected](/docs/setup/configure-webhub) and, when applicable, ensure Notification URL from the FinDock Setup (for the payment extension) is correctly added to the PSP dashboard settings. |
| “Cannot deserialize instance of date from VALUE_STRING value 04-05-1986 or request may be missing a required field”
"Unknown field: cpm.API_Request_Response.ABC.XYZ"
“System.NullPointerException: Attempt to de-reference a null object”
or similar error | The API uses strict deserialization, so you cannot use parameters and values that are unknown to the API as request parameters, or as a (custom) field on the sObject you are trying to update. These errors can also be thrown when a call from the API triggers logic in Salesforce that tries to copy/update other objects.1. Check if the fields you are using are present on the sObject you are trying to update.
2. Check if you are using the correct format for custom fields on Standard Salesforce Objects like Contact (e.g. `TwitterHandle__c`, including `__c`).
3. Check if you are using the correct format for passing custom fields on Custom Salesforce Objects like Payment in the API (e.g. `cpm__Bank__Account__c`, including the package namespace prefix).
4. Check if updating one of the sObjects in the API (like Contact, Installment, Payment) triggers logic like mapping Installment fields to Opportunity fields (standard in NPSP) or other sObjects. If this is the case, check if the field you are updating (like campaign) is available and accessible on *all* objects in the chain.

 |


## Tools to help troubleshooting

The root cause of a Payment API issue can be either in your API call, the API, other (3rd party) packages, Salesforce or customization of the Salesforce org. There are several tools at your disposal to narrow down the origin of the problem.

### Salesforce Workbench

To quickly simulate an API call with an authenticated user, you can use the Salesforce Workbench. Since you will be executing the call from an authenticated context and probably with an admin user, this is a quick way to find out whether you have issues with authentication. It also allows you to test out use cases without coding to see if the Salesforce and FinDock configuration are working correctly.

To use Salesforce Workbench:

1. Go to the [Workbench](https://workbench.developerforce.com).
2. Select Production (if you are using a Production environment or Developer org) or Sandbox.
3. Log in with Salesforce and click **Allow Access**.
4. Go to **Utilities** > **REST Explorer**.
5. Set URL to `/services/apexrest/cpm/v2/PaymentMethods` or one of our other endpoints.
6. Select the right operation (e.g. GET or POST).
7. If trying to perform a POST, add a request body.
8. Click **Execute**.


The workbench shows you the response both Structured and Raw.

![Salesforce Workbench Payment API testing](/assets/salesforceworkbench_api_testing.6c7eb37c28f3b5049491cfedf94dd39cf1d7b51087d9ff56fd7248096a951919.c5aff763.png)

A tool like [Postman](https://www.postman.com/) is very helpful for advanced development and testing of your API requests. For simple testing, you can also use our [browser-based test app](/api/getting-started-with-the-payment-api-v2#step-0-create-a-test-app-integration-optional).

### Inbound Report records

If you see no Installment or Recurring Payment record, you can check the inbound report using the paymentIntentId returned in the API call.  If the status of the record is not updated, or an expected record, like mandate and payment profile, is missing, you can check the inbound report created for the notification from the Payment Service Provider (PSP).

For more guidance, see [failed payment intents](/assets/failed-payment-intents.7199467cfd19b71282b4827acb343c15344d7e891134e9f7f3d13bd3c3273ba2.9f4632b3.md).

### Log records

When a Payment API request or outbound webhook notification results in an error, FinDock creates a Log record in Salesforce.

For requests, the initial request and error are stored on the **Message** field.

![API Log record example](/assets/api-log-record.5d8d5bdafdc70998247347572316daef35b4050312fd79de4bef837c0aa34dc3.c5aff763.png)

For outbound webhook notifications, the following data in the **Message** field:

* Webhook Url: `<url>`
* Outbound Payload: `<generated Payload>`
* Exception: `<Exception message - exception stack trace>`


### Message records

FinDock stores all inbound and outbound messages in the Messages object in the FinDock app including, for instance, the payload of the message. You can find them under **FinDock** > **Messages** in Salesforce.

* If you do not find a message corresponding to the webhook call of the payment processor, check the settings related to the Remote Site Settings and Callback URL as described above.
* If the status of the message is 'Scheduled' instead of 'Finished,' wait for a little while and check again. FinDock handles processor callbacks asynchronously.
* If the status of the message is ‘Failed,’ check ‘Failure Reason’ in the error section.


![FinDock Messages object example](/assets/findock_messages_object_example.5ea484525d65b68e7358ed923e35561eac00b82143d7debe3fb0c9084195313b.c5aff763.png)

### Salesforce object history

Salesforce tracks the history of important fields like Status and Amount on FinDock objects, such as Installment. You can find the history in the Related section of a specific record. This can give you clues as to what did and did not happen and which user performed what action(s).

![Salesforce object history example](/assets/salesforce_object_history_example.b434fac674059507db37ea72402748082a9640f04fd0a13dd7c23fce2accd4f4.c5aff763.png)

### Verbose header parameter

If the Response Code and Error Message are too generic, you can add a header parameter ‘verbose’ with value ‘true.’ This returns the original status code and error thrown by Salesforce. **Example with Status Code = 500**


```json
"Error": {
        "error_message": "Invalid request. Please read the documentation or contact support.",
        "error_code": "999",
        "typeName": "API_Request_Base.ApiException",
        "stackTraceString": "Class.API_Payment_POST_V1_0.determinePaymentMethodAndEnrichRequestIfRequired: line 113, column 1\nClass.API_Payment_POST_V1_0.getPaymentMethodNameForPSP: line 37, column 1\nClass.API_Payment_POST_V1_0.validateRequestParameters: line 572, column 1\nClass.API_Payment_POST_V1_0.prepareData: line 246, column 1\nClass.API_Payment_V1_0.postPayment: line 69, column 1",
        "lineNumber": 113
}
```

Since the code for managed packages in Salesforce (like FinDock) is obfuscated, you do not see a full stack trace or the actual code. However, information like the namespace and Apex class names can help you narrow down in which package the error has occurred to start root cause analysis. Common packages and namespaces found in Salesforce implementations with FinDock include but are not limited to:

* `cpm` = FinDock Core package namespace
* `npsp` = Salesforce Nonprofit Success Pack source connector package
* `fdff` = Fundraising source connector package


FinDock Support can use the error message to deep-dive the root cause if the issue was caused by our package.

### Salesforce logs

Salesforce debug logging on, for example, the (integration) user you have chosen to acquire an authentication token and connect the WebHub with, can help narrow down the cause of an issue. Please refer to the [Salesforce Set Up Debug Logging article](https://help.salesforce.com/articleView?id=code_add_users_debug_log.htm&type=5) for more information.

### Payment processor dashboards

Almost all Payment Service Providers (PSPs) provide a dashboard, like the screenshot below, where you can check actions initiated by the FinDock Payment API. With these dashboard, you can check, for instance:

* Whether following the redirectURL returned in the response has led to (the correct) data with the PSP
* View what data (like amount, status of the payment) should have been sent from the PSP to FinDock
* Some PSPs even tell you what exact *events* were sent to what *endpoint*, so you can further pinpoint where the root cause can be found.


This information can help you determine whether the issue is with FinDock configuration, the PSP configuration or your API call.

![PSP dashboard example](/assets/psp_dashboard_example.cc8e1e4b8ae497466bf32f57e3e470314b82f56f60ca7f30e5acc2f769ab0f35.c5aff763.png)