Creating a Dispute

πŸ‘

Notice

This guide is in a preliminary state for a feature that is a work in progress. The contents of this document may change at any time without notice.

This guide explains how to use the Dispute API endpoints to initiate and submit a dispute.

Account holders have the right to dispute a charge when they question the legitimacy of a transaction that was posted to the account. Account holders dispute transactions for a number of reasons, including but not limited to:

  • Duplicate transaction
  • Unauthorized transaction
  • Unrecognized account
  • Overcharging
  • Item or service not provided
  • Item or service not satisfactory

With Galileo's Dispute API endpoints, you can integrate the dispute process into your mobile app or website to provide account holders with a seamless dispute experience. The account holder's experience might be as simple as this:

  1. Click a "dispute transaction" button or link.
  2. Select one or more transactions to dispute.
  3. Answer a series of questions about the transactions.
  4. Fill out additional documents, if required.
  5. Submit the dispute.
  6. If later adjustments need to be made to the dispute, such as attaching more documents, edit the dispute.
  7. Track the status of the dispute until completion.

Using the Dispute API endpoints also ensures that disputes are made in compliance with card network requirements and regulations such as Regulation E and Regulation Z. Any updates to the requirements are accounted for on the backend, without disrupting your workflow.

Galileo has developed a conversational API for its disputes function. A "conversational" API is a series of calls that are made in a certain order, with the response from one call providing the data for the next call. By using a conversational API, Galileo makes it possible to tailor the user experience according to the nature of a given dispute and also to conform to regulations governing disputes. For example, if an account holder indicates that a disputed transaction is a duplicate, you can provide follow-up questions that are specific to duplicate charges, whereas an account holder who indicates suspected fraud will get questions that are related to fraud.

Result of following this procedure

A dispute has been entered into the dispute system. The information gathered and submitted for the dispute conforms to either Reg E or Reg Z, depending on the characteristics of the account and account holder.

UI requirements

For your mobile app or web site, create a user interface that permits account holders to initiate and submit a dispute.

  • The dispute-creation process involves multiple steps that must be performed in the order shown in the numbered steps below.
  • The UI must be flexible enough to display dynamic responses from the endpoints, which are returned depending on the characteristics of the dispute that were indicated in earlier endpoints calls. Some responses from the account holder will trigger further displays, and so on.
  • You should include an interface for uploading files.

Dispute-creation workflow

Follow these steps to create a dispute. Unless otherwise specified, call the endpoints in the order shown here.

πŸ“˜

Note

To test connectivity to the Dispute API, use the specialty Ping endpoint that is for the Dispute API only. Do not use the Program API Ping endpoint.

1. Initiate the case and obtain the case reason

Initiate the case, obtain the case reason from the account holder, and send it back to Galileo.

629629
  1. The account holder initiates a dispute on your mobile app or website by clicking an "initiate dispute" control.
  2. You call the Create Case endpoint with the PRN, PAN, or CAD of the account.
  3. Galileo returns the caseId. You pass caseId for all subsequent calls for the case.
  4. You call Get Case Reasons with the caseId.
  5. Galileo returns a JSON containing the case reason types and case reasons. The response varies depending on the account and user type. For example, a consumer debit account might get a different response than a business credit account.
  6. You present the case reasons to the account holder. See "Presenting the case reasons," below, for instructions.
  7. The account holder selects the category and reason.
  8. You pass the category and reason back to Galileo in the Add Case Reasons call. See Returning the case reasons for more information.
  9. Galileo returns status: 0.

Presenting the case reasons

Use the response from the Get Case Reasons endpoint to populate a screen that prompts two interactions with the account holder. First, the account holder selects a case reason type (ClaimReasonType) and then selects a case reason (ClaimReason).

The JSON in the response is structured as answerList levels nested inside questionList levels. The first level contains the case reason type in the top level, and then when the account holder selects one of the types, you present the corresponding case reasons in the next level down.

This is an example of the first screen to present. The values in parentheses are identifier values in the Get Case Reasons response. You may get a different set of fields in the response depending on the account and account holder types.

Which of the following would you like to report? (ClaimReasonType)

  • I made this purchase, but there is a problem and I need to dispute it. (NonFraud)
  • I did not authorize this transaction. I suspect fraud. (Fraud)
  • I had an issue while using my card at an ATM. (NonFraudATM)

When the account holder selects a case reason type, present the case reasons that are nested in the corresponding answerList. The case reasons should have radio-button controls so that the account holder can select only one case reason. For example, if the account holder selects NonFraud, present these options:

Which of the following best describes the reason for your dispute? (ClaimReason)

  • I was charged or credited incorrectly. (ChargedCreditedIncorrect)
  • I am dissatisfied with the merchandise or a service I received. (MerchandiseServiceIssue)
  • I continue to be charged for a recurring transaction after I canceled. (MerchantRecurring)
  • I canceled or returned the merchandise or service and have not received the expected credit. (MerchantCreditNotIssued)
  • I haven't received merchandise or a service I purchased. (MerchantNotProvided)
  • I was charged more than once. (MerchantDuplicate)

πŸ“˜

Note

You cannot add your own case reason type or case reasonsβ€”they will not be recognized by the dispute system.

Returning the case reasons

When the account holder selects the case reason type and case reason, pass them back to Galileo by calling the Add Case Reasons call. Populate reasonType with the case reason type and reason with the case reason. Use the value in the Identifier field of the Get Case Reasons response.

These are the valid reasonType and reason combinations for the example shown above.

reasonTypereason
NonFraudMerchantDuplicate
MerchantNotProvided
MerchantCreditNotIssued
MerchantRecurring
MerchandiseServiceIssue
ChargedCreditedIncorrect
FraudCardLost
CardStolen
CardNotReceived
CardSecure
NonFraudATMATMPar

2. Select transactions

Present a list of eligible transactions for the account holder to select and pass the transactions back to Galileo.

616616
  1. You call Get Transactions with the caseId. You pass start and end dates and optionally the amount and merchant name as filters.
  2. Galileo returns a list of transactions that are eligible for dispute and that fit the filter criteria.
  3. You present the list of transactions to the account holder. The list should have check-box controls to select multiple transactions. See "Transaction entries," below, for more information.
  4. You submit the transaction IDs of the selected transaction(s) in the Add Transactions call. See Submitting the transactions for the restrictions on this call.
  5. Galileo returns status: 0.

Transaction entries

Each entry that is returned by Get Transactions contains these metadata fields:

  • authorizationStatus β€” The only valid value is Posted.
  • debitCredit β€” Whether the transaction debits or credits the account:
    • Debit
    • Credit
  • transactionType β€” The type of transaction. Possible values:
    • ACH β€” ACH transaction
    • ATMDEP β€” ATM deposit
    • ATMWD β€” ATM withdrawal
    • CardPinless β€” Card transaction without PIN (signature)
    • CardPinned β€” Card transaction with PIN
    • CHECK β€” Paper check deposit
    • FEE β€” Fee
    • P2P β€” Peer-to-peer transfer
    • WIRE β€” Wire
  • description β€” The description of the transaction.
  • amount β€” Transaction amount. Unsigned.
  • cardNumberEndingIn β€” Last 4 digits of the PAN.
  • date β€” Date of the transaction: YYYYMMDD.
  • transactionId β€” Identifier assigned by the disputes platform

You may need to record each disputed transaction with its metadata so that you can make the correct decision if you are awarding provisional credit. See After submitting the dispute for more information.

Submitting the transactions

When submitting the transactions using the Add Transactions endpoint, you must follow these rules, depending on the reasonType that you submitted with the Add Case Reasons call:

  • If reasonType != Fraud, all transactions submitted in an Add Transactions call must be from the same merchant. If the account holder has selected transactions from multiple merchants, send multiple Add Transaction calls with the transactions from the same merchant bundled together.
  • If reasonType = Fraud, the transactions in the same call can be from different merchants.

3. Get follow-up questionnaire answers

According to the reason that the account holder returned, present the follow-up questions.

630630
  1. You call Get Questionnaire with the caseId.
  2. Galileo returns a JSON of the questionnaire.
  3. You present the questionnaire to the account holder, according to the contents of the response. See "Presenting the questionnaire," below, for instructions.
  4. The account holder answers the questions.
  5. You pass the answers back to Galileo with the Add Questionnaire call. See Returning the answers to the questionnaire for instructions.
  6. Galileo returns status: 0.

Presenting the questionnaire

The questions that you receive in the response to Get Questionnaire will vary according to the reason that you passed in the Add Case Reasons call as well as the network. The response may contain hundreds of lines of JSON formatting.

As with the JSON in the Get Case Reasons response, there are answerList levels nested inside questionList levels. However, instead of only two levels of questions, the number of levels that you will use depends on the answers that the account holder provides in each level.

If you submitted reasonType: Fraud and reason: CardSecure ("I didn't make the purchase, but I still have my card.") in the Add Case Reasons call, the questionnaire that Get Questionnaire returns is called FraudCardSecure. The next level down is a questionList called CardPossession that contains two questions.

This is the first question to present:

{
"type": "YesNo"
"identifier": "CardPossessionInd"
"displayText": "Do you always have possession of the card?"
"dataType": "String"
}

Nested inside that questionList level is the answerList with two possible answers, Yes and No, and nested inside each of those answers are follow-up questions that you display depending on which answer the account holder selects. If the account holder selects Yes then there are no further questions to display for that answer. If the account holder selects No, then you display two more questions, each with a text box for the answer:

{
"type": "Text"
"identifier": "CardLocation"
"displayText": "Where is the card usually kept?"
"dataType": "String"
}
{
"type": "Text"
"identifier": "CardNoPossession"
"displayText": "In what circumstances do you not have the card in your possession?"
"dataType": "String"
}

After the account holder answers those questions you present the next set of four questions, which are inside vsq1. This is the first of those questions:

{
"type": "YesNo"
"identifier": "HasAuthorizedOthers"
"displayText": "Have you ever authorized another person to use your card?"
"dataType": "String"
}

As the account holder answers the questions, present any follow-up questions that are nested inside the answers until you reach the end of the node, and then go to the next question in that level. Capture the identifier and the answer for each question answered to return in Add Questionnaire, as described in the next step.

This is one possible sequence of answers for the FraudCardSecure questionnaire. The identifier for the question is shown in parentheses:

  • Do you always have possession of the card? (CardPossessionInd)
    • No
      • Where is the card usually kept? (CardLocation)
        • "In my purse"
      • In what circumstances do you not have the card in your possession? (CardNoPossession)
        • "When I go to the gym"
    • Have you ever authorized another person to use your card? (HasAuthorizedOthers)
      • No
    • Have you ever shared your Personal Identification Number (PIN)? (HasSharedPIN)
      • No
    • Where do you keep your PIN? (WherePinKept)
      • In memory (InMemory)
    • Due to the fraud on your account, would you like to cancel your card now? (CancelCardInd)
      • Yes
    • Would you like us to send you a replacement card? (ReissueCard)
      • No
        • Should the account be closed permanently? (ConfirmAccountClosure)
          • Yes

After presenting the main parts of the questionnaire, you display the postQuestionnaire questions, which permit the account holder to add information such as comments or to attach further documents.

  • Do you have any additional information to provide about this dispute? (AddlInfo)
    • No
  • Do you have any additional information that should be provided to the merchant regarding your dispute? (HasVisaComments)
    • No

Returning the answers to the questionnaire

The questionnaire parameter in the Add Questionnaire endpoint accepts a JSON list (questionList) that contains identifier/answerValue pairs. identifier contains the identifier for the question in the Get Questionnaire response and answerValue contains the response that the account holder selected or entered.

This example shows what you would return for the questions in the example section, above:

questionnaire: {
    "questionList": [
        {
        "identifier": "CardPossessionInd",
        "answerValue": "No"
        },
        {
        "identifier": "CardLocation",
        "answerValue": "In my purse"
        },
        {
        "identifier": "CardNoPossession",
        "answerValue": "When I go to the gym"
        },
        {
        "identifier": "HasAuthorizedOthers",
        "answerValue": "No"
        },
        {
        "identifier": "HasSharedPIN",
        "answerValue": "No"
        },
        {
        "identifier": "WherePinKept",
        "answerValue": "InMemory"
        },
        {
        "identifier": "CancelCardInd",
        "answerValue": "Yes"
        },
        {
        "identifier": "ReissueCard",
        "answerValue": "No"
        },
        {
        "identifier": "ConfirmAccountClosure",
        "answerValue": "Yes"
        },
        {
        "identifier": "AddlInfo",
        "answerValue": "No"
        },
        (
        "identifier": "HasVisaComments",
        "answerValue": "No"
        )
  ]
}

4. Attach documents

Depending on the case reasons and the transactions selected, the account holder may need to fill out a form. Other documents can be attached to the case as well, as prompted in the post-questionnaire.

686686
  1. You call Get Doc Requirements.
  2. Galileo returns one of two options:
    • A message saying that no further documents are required.
    • A base64-encoded PDF (templateDocumentationStream) that the account holder must fill out and return. When the account holder has filled out the form, you call Add Required Docs to send the completed form to Galileo.
  3. The account holder optionally clicks an "Attach Documents" control (which may be included in the post-questionnaire flow instead of being after Add Questionnaire) and uploads files such as screenshots and receipts to your interface.
  4. You call Add Attachments to attach the files to the case.

πŸ“˜

Note

If the account holder does not fill out and return the required PDF before submitting the case, you can add the PDF form later using Add Attachments. Make sure you keep track of which required documents have not yet been submitted.

5. Finalize the case

The account holder clicks "submit" at the end of the process.

642642
  1. The account holder clicks a "submit" control to signal that they have finished inputting information for the dispute.
  2. You call Submit Case. The "Requirements for submission," below, must be fulfilled.
  3. Galileo returns success and sends the DSCT: dispute_created event message.

Requirements for submission

Before you can call Submit Case, these minimum requirements must be fulfilled:

  1. The case number was created. (Create Case)
  2. The case-reason category and reason were submitted. (Add Case Reasons)
  3. One or more transactions were submitted. (Add Transactions)
  4. The questionnaire answers were submitted. (Add Questionnaire)

πŸ“˜

Note

If the account holder begins the dispute process but does not complete it, the case that was created remains in the dispute system for eight hours and then times out. If the account holder decides to return to a case that has timed out, you have to start over with Create Case to create a new caseId.

After submitting the dispute

Depending on the type of transaction that was disputed, the appropriate party evaluates the dispute and returns a verdict. Card transactions are evaluated by the card networks and banks evaluate the other transaction types.

In some cases, it is appropriate to award provisional credit before the verdict is returned. Consult with Galileo for ways to implement provisional credit. Galileo can handle provisional credit for you, or if you handle it yourself, use the transaction metadata that was returned by Get Transactions, along with account and account holder information, to help determine if or how to award provisional credit. Consult Regulation E and Regulation Z for more information.

When the verdict is returned in the account holder's favor, the provisional credit becomes permanent, or if the verdict is in the other party's favor, the provisional credit is removed from the account. Galileo notifies you of the verdict using the DSFP: dispute_final_pc or DSFN: dispute_final_no_pc event message, depending on whether provisional credit was already awarded. From these events you can determine which communication to send to the account holder, such as a paper letter. You can make arrangements with Galileo to send the letters or you can send your own.

Add documents to the case

Before the verdict arrives, if the account holder wants to add more documents to the case, or if the account holder needs to return the required PDF form, call Add Attachments with the case ID to attach the documents.

Events API messages

These events are associated with dispute creation and resolution. You can arrange with Galileo to receive these events:

  • DSCT: dispute_created β€” The dispute has been submitted using Submit Case.
  • DSPC: dispute_pc β€” Provisional credit has been awarded to the account holder, before the verdict is returned.
  • DSFP: dispute_final_pc β€” A dispute for which provisional credit was awarded has been finalized. The verdict is in the dispute_resolution field.
  • DSFN: dispute_final_no_pc β€” A dispute for which provisional credit was not awarded has been finalized. The verdict is in the dispute_resolution field.

Did this page help you?