All articles
July 15, 2026 · 8 min read

ARCA cards and 3-D Secure: what an online merchant in Armenia needs to know

How card payments in Armenia reach you through ARCA and its member banks, the terminal credentials your bank issues, what 3-D Secure changes in practice, and how refunds work according to the Paynet API.

Cards are still the method that reaches every buyer, including the ones abroad paying an Armenian shop. In Armenia those payments run through ARCA, the national card network, and through the member banks that do the acquiring. This post covers the parts a merchant actually has to handle: who gives you what, what 3-D Secure changes, how to test, and what the API says about refunds.

Who is who in a card payment

Three parties sit behind one button on your checkout.

  • The card network. Visa, Mastercard and ArCa cards are processed through ARCA and its member acquiring banks.
  • Your acquiring bank. This is who you sign the internet acquiring contract with, who sets your rate, and who settles the money to your account. Ameriabank, Inecobank, Evocabank, Converse Bank, AraratBank, ACBA, AmioBank, IDBank, Ardshinbank and other ARCA member banks each act as their own processor, with their own credentials and their own checkout option.
  • The gateway. Paynet sits in front of all of them so your store speaks one API and one checkout instead of one per bank. It does not hold your money and does not replace your bank contract.

That last point is the one to internalise. Adding a gateway does not change who you signed with, what your acquiring fee is, or who pays you. It changes how many integrations you maintain.

The credentials your bank gives you

Card credentials are short, which surprises people expecting a folder of files. For ARCA and the member banks running the ARCA stack you get:

  • an API username
  • an API password

That is it. The gateway address is decided for you per provider, so there is nothing else to configure. Ameriabank's gateway is the one exception in the set: it authenticates with a username, a password and a Client ID.

Two practical wrinkles come with bank credentials:

  • IP whitelisting. Some acquirers accept payment requests only from addresses they have registered against your merchant account. Inecobank works this way. Because you hold the bank contract, you are the one who can ask, and Paynet shows you the exact address to send the moment you pick such a provider. Until your bank registers it, every payment through that provider fails, and no amount of correct code fixes it.
  • Which gateway variant you are on. Provider settings include an EPG option, which uses the ARCA EPG gateway instead of iPay. If your bank told you which one your terminal lives on, set it to match. If they did not, ask, rather than guessing and debugging a rejected login later.

Keep the credentials where they belong. In Paynet they are stored encrypted at rest, and the routes that touch keys and credentials ask you to confirm your password again. Card data itself never reaches you at all: buyers enter card details on the licensed processor's page, so it is never stored on your server and never becomes your liability.

What 3-D Secure changes

3-D Secure is the step where the card issuer verifies the cardholder before approving an online payment, usually with a one-time code or a confirmation in the bank's own app. From a merchant's point of view it changes three things, and all three are about your order handling rather than your payment code.

The buyer leaves your site for longer, through more screens. A card payment already meant a redirect. With verification in the middle, there are more places a buyer can hesitate, close the tab, or lose a signal.

More payments end in a state that is not simply "declined". Verification can fail on its own, separately from the card being good. Paynet surfaces that distinctly: the checkout tells the buyer "Card verification failed. Please try again", which is a different message from "The card was declined" or "There are not enough funds on the card". Show the difference in your own admin too. A verification failure is usually worth a retry, and a decline usually is not.

Timing gets less tidy. A payment stays open for 20 minutes before it expires, while the checkout_url itself remains valid for 24 hours. And a late confirmation from the provider can move a payment that already read failed or expired to completed. That is not a bug to work around, it is the reality of a buyer who finished authenticating just after your patience ran out. Always act on the latest state you read, not on the first webhook you saw, and never mark an order paid because a browser arrived at your thank-you page. Verify the webhook signature, dedupe on delivery_id, then read the truth back with GET /api/v1/orders/{order_id}/payment.

There is also a QR variant of card payment in the family. With ArcaQR the buyer scans a code with their bank app to pay, and the code is short lived: the checkout counts down a QR that is valid for 60 seconds and offers a fresh one when it expires.

Testing card payments before you go live

Card processors are the part of the Armenian payment landscape where you can rehearse properly, because ARCA is the one family with a real test environment. Two layers are available, and you want both.

The Paynet sandbox, for your own code. Install the Sandbox provider and send "processor": "sandbox", or use a test API key beginning with sk_test_. No bank is contacted, nothing moves, nothing is counted. The card number picks the outcome, which is what makes it useful for card work specifically:

  • 4111 1111 1111 1111 approved
  • 4000 0000 0000 0002 declined by issuer
  • 4000 0000 0000 0069 insufficient funds
  • 4000 0000 0000 0101 3-D Secure failed
  • 4000 0000 0000 0119 processor timeout
  • 4000 0000 0000 0127 amount limit exceeded
  • 4000 0000 0000 0200 duplicate transaction
  • 4000 0000 0000 0259 transaction expired
  • 4000 0000 0000 0309 processor unavailable
  • 4000 0000 0000 0341 general failure

Run the 3-D Secure failure case deliberately and look at what your store shows the buyer and what your support team sees. That five minutes is worth more than any amount of reading.

The bank's own test terminal, for your credentials. ARCA-family providers support a test mode with separate test credentials. Your bank assigns an OrderID range for test payments, and you enter its start and end in the provider settings; test payments then use the next unused number in the range and never reuse one. If your bank gave you a test terminal, use it before switching the provider to production.

Either way, live payments start only after your business is verified. Until then everything works in test mode, with unlimited free test payments, so there is no reason to wait for paperwork before building.

Refunds, as the API describes them

Refunds are one call: POST /api/v1/payments/{uuid}/refund. The body takes an optional amount, which defaults to the full remaining balance, and an optional reason. What matters is the handful of rules around it.

  • Full and partial refunds behave differently in the record. A completed payment becomes refunded only on a full refund. A partial refund leaves the status completed and raises refunded_amount above zero. If your reconciliation only looks at status, partial refunds will quietly go missing from it.
  • Send an Idempotency-Key. With one, the same key on the same payment returns the same refund, 201 when it is created and 200 on a replay. Without one, a second call is a second refund. If a refund call times out, read the payment back with GET /api/v1/payments/{uuid} before retrying anything.
  • Read the error codes, they mean different things. not_refundable, already_refunded, refund_in_progress, refund_declined, processor_unavailable and refund_outcome_unknown all arrive as 409, and refund_not_supported, invalid_amount and amount_exceeds_remaining as 422. A refund whose outcome is unknown is not the same as a refund that failed, and treating them alike is how a customer gets paid twice.
  • Refunds fire webhooks too. A payment.refunded event goes to the payment's callback_url, carrying the refund uuid, amount and reason.
  • Keys can be scoped. An API key created as payments only can create and read payments and links but cannot refund or buy units, and gets 403 insufficient_scope if it tries. Give that key to a storefront or a contractor and keep full-access keys on your own server.

On the pricing side, refunds themselves are free. The transaction unit you spent is not restored, because it was a successful payment when it happened. Failed payments and all test payments cost nothing either. The rest is on the pricing page.

What to do next

  • Confirm with your acquiring bank which credentials you hold: username and password, plus a Client ID if you are on Ameriabank, and whether your terminal is on the EPG or iPay gateway.
  • If your bank whitelists addresses, send them the IP shown on the provider screen before you test anything.
  • Add the provider in Paynet, connect it to your verified domain, and check the domain lists it as an active method.
  • Run the sandbox card list end to end, including the 3-D Secure failure, and make sure your admin distinguishes verification failures from declines.
  • Decide, in code, how you handle a late confirmation and a refund with an unknown outcome.
  • The full endpoint reference, including refunds and webhooks, is at paynet.am/docs/api, with the shorter tour on the developer page.

ARCA, Visa, Mastercard and the bank names above are trademarks of their respective owners. Paynet is an independent payment gateway operated by Digital Brains LLC in Yerevan; merchants hold their own acquiring contracts.