We had a merchant whose "fraud" chargebacks kept creeping up. Fraud tooling showed nothing odd. Cardholders were real, the 3DS pass rate was normal, and the orders shipped.

The reason code on most of them was "unrecognized transaction".

We pulled a sample of settled transactions and compared the descriptor we sent with what showed up in the acquirer's clearing file. We sent ACME GLOBAL MARKETPLACE*ORDER48213. The file had ACME GLOBAL MARKETPLAC. Our API accepted 40 characters. The acquirer truncated at 22 and kept the front, so the order reference we put at the end of the string was gone, and the brand name was cut mid-word. A customer scrolling their banking app saw something that matched nothing they remembered buying.

The fix was boring. We moved the recognizable short brand to the front (ACME*ORDER48213), validated the length at the edge of our own API instead of trusting the gateway's limit, and logged the descriptor we sent next to the one in the clearing file.

The lesson for me: "request accepted" and "value delivered to the cardholder" are different checks. Any free-text field that crosses a network boundary can get cut silently.

Do you diff what you sent against what came back in settlement files, or only against the API response?

Payneteasy handles this kind of payment flow for merchants and PSPs — see how it works.