Stripe

Connect a merchant's own Stripe account to process credit card transactions through Preczn.

Stripe is a direct connection: each merchant supplies their own Stripe API keys, and Preczn transacts against that merchant's own Stripe account. There is no platform-level Stripe secret, and no merchant is created at Stripe by Preczn.

📘

Stripe or Stripe Connect?

Use Stripe when each merchant already has — or will open — their own Stripe account and gives you its API keys. Use Stripe Connect when merchants are connected accounts under your own Stripe platform, boarded and managed by you. The two are separate connections in Preczn and a merchant can hold both.

Before You Start: Raw Card Data Access

Preczn holds the card in its own PCI-compliant vault and sends the card details to Stripe server-to-server. That path uses Stripe's raw card data APIs, which Stripe does not enable by default — an account that has never requested access can create a connection in Preczn but cannot process a transaction with it.

Enabling it takes two steps:

  1. Contact Preczn support for our current PCI DSS Attestation of Compliance.
  2. Ask Stripe Support to enable raw card data APIs on the account, and share that Attestation with them.

The card data is stored and transmitted by Preczn, so Preczn's Attestation is the compliance evidence Stripe is asking for — there is nothing for the merchant to fill out.

❗️

Do this before sending live transactions

Without raw card data access, every transaction fails with an E (Error) carrying Stripe's own message about the account not being permitted to send raw card data. Stripe can grant test-mode access without the documentation, so sandbox work is not blocked while the live request is in progress.

Supported Capabilities

CapabilityStatusNotes
Credit Card TransactionsSupportedSale, auth, capture, void, refund, and verify
Apple Pay / Google PaySupportedSee Wallets
ACH (Bank Account) TransactionsNot supportedStripe is never selected for an ACH transaction — see ACH
Merchant OnboardingNot supportedMerchant accounts are opened with Stripe directly, then linked in Preczn
Historical Transaction ImportSupportedOne-time import of past Stripe transactions — see Importing Existing Stripe Transactions

Supported Transaction Types

TypeCardDescription
SaleAuthorize and capture in a single request
AuthAuthorize only (hold funds without capturing)
CaptureCapture a previous authorization, in full or in part
VoidCancel an authorization (see Voids)
RefundReturn funds from a completed sale or capture
VerifyValidate a card without moving funds

ACH

Stripe is a card-only connection in Preczn. It is not eligible for ACH routing, so an ACH transaction in a plan that contains Stripe is routed to an ACH-capable connection instead and never reaches Stripe. To accept bank account payments, add a connection that supports ACH.

Credentials

All Stripe credentials live on the merchant, not on the platform connection.

CredentialLevelWhere it comes from
Public KeyMerchantThe merchant's Stripe dashboard — pk_test_… / pk_live_…
Secret KeyMerchantThe merchant's Stripe dashboard — sk_test_… / sk_live_…

Both are required. A merchant's Stripe connection stays Unconfigured until both keys are present. Stripe calls the public key the publishable key; it is the pk_-prefixed value in the merchant's Stripe developer settings.

Adding the Platform Connection

The platform connection carries no credentials — it exists so Stripe appears in your plans and on your merchants.

  1. Select Connections from the left-hand navigation.
  2. On the Add Connections tab, select Connect under Stripe.
  3. Enter a name for the connection.
  4. Optionally enable Import Merchant Transaction History — see Importing Existing Stripe Transactions.
  5. Save the connection.

Saving also creates a Default Stripe Plan for routing.

Adding a Merchant's Stripe Keys

Dashboard

  1. Navigate to Merchants and open the merchant.
  2. In the merchant's Connections pane, select Stripe.
  3. Enter the Public Key and Secret Key.
  4. Save. Preczn verifies the keys against Stripe before storing them.
⚠️

Key prefixes must match the mode

A Test Mode merchant requires sk_test_ and pk_test_ keys; a Live merchant requires sk_live_ and pk_live_ keys. A mismatch is rejected before the connection is saved, with either Invalid credentials. Test credentials cannot be used in live mode. or Invalid credentials. Production credentials cannot be used in test mode. There is no environment field to set — Stripe reads the environment from the key itself.

Merchant Import

Include the keys when importing merchants via CSV, using these column headers:

ColumnDescription
public_keyThe merchant's Stripe public key
private_keyThe merchant's Stripe secret key

API Integration

Configure the keys programmatically with the Update Connection Details endpoint:

curl --request PATCH \
  --url https://api.preczn.com/v1/merchants/{merchantId}/connections/Stripe \
  --header 'Authorization: Bearer {api_key}' \
  --header 'Content-Type: application/json' \
  --data '{
    "key": "pk_live_...",
    "secret": "sk_live_..."
}'

Request Fields

FieldTypeRequiredDescription
keystringYesThe merchant's Stripe public key
secretstringYesThe merchant's Stripe secret key

Neither value may contain spaces. Sending only one of the two is rejected with Stripe requires fields : secret,key, naming whichever field is missing.

Verification

Preczn verifies a merchant's keys by reading the Stripe account they belong to. Verification confirms that Stripe accepts the secret key and that the key can read its own account. It does not confirm that the account can process transactions — that additionally requires raw card data access.

📘

Restricted keys

Stripe restricted keys can be scoped so narrowly that Preczn cannot verify or transact with them. A restricted key must at minimum permit reading the account for verification to succeed, and each capability you intend to use — charges, refunds, webhook endpoints, payment methods — needs its own permission. A standard secret key avoids this entirely, and can be revoked independently of the merchant's other keys.

Processing Transactions

Route transactions to Stripe the same way as any other connection — through a plan or a direct connection reference on the transaction. The sections below cover the behavior specific to Stripe.

Transaction Records at Stripe

Preczn creates a Stripe payment intent for every sale and auth, and a Stripe refund for every refund. Captures and voids act on the original payment intent. The processorTransactionId on the Preczn transaction is the id of the matching Stripe object, so it can be used to find the transaction in Stripe.

Every payment intent and refund also carries a precznId in its Stripe metadata, holding the Preczn transaction id.

Captures

A capture may be for the full authorized amount or for less. Preczn sends the amount on the capture request when it is lower than the authorized amount; capturing less than the authorized amount releases the remainder of the hold at Stripe.

Voids

A void cancels the payment intent behind an authorization. Only an uncaptured authorization can be voided:

  • An authorization that has already been captured is rejected by Preczn with Auth already captured. Use refund instead.
  • A completed sale is captured the moment it is approved, so Stripe cannot cancel it. Reverse a sale with a Refund instead.

Refunds

A refund may be full or partial, and is issued against the original sale or capture. A Stripe refund can come back Pending and settle later — see Pending Transactions.

Verify

A Verify creates the card at Stripe and confirms a setup intent against it, which sends the card to the issuer for validation without moving funds. The response carries the AVS and CVV results, and processorTransactionId holds the Stripe payment method id rather than a payment intent id.

📘

Read the AVS and CVV results, not just the status

A Verify is reported as Approved whenever Stripe accepts the request. The meaningful signal is the AVS and CVV result on the response — a card that Stripe accepted but whose address or CVV did not match still returns Approved with N or U results.

Wallets

Apple Pay and Google Pay transactions can be routed to Stripe. Preczn decrypts the wallet payload and passes the network token and cryptogram through, so the transaction is processed as a wallet payment at Stripe.

❗️

Wallets need a second feature enabled at Stripe

Raw card data access covers ordinary card transactions. Sending decrypted wallet data is separate — ask Stripe Support to enable the decrypted tokens feature on PaymentIntents and SetupIntents for the account. Until it is on, Stripe rejects the network token and cryptogram fields and the wallet transaction fails.

Google Pay is the exception worth knowing: a Google Pay payment backed by a device token (CRYPTOGRAM_3DS) is sent as a network token, but one backed by the card's real number is sent to Stripe as an ordinary card transaction, with no wallet marker.

See Apple Pay on the Web and Google Pay for Web for the client-side setup.

3D Secure

Preczn processes Stripe authorizations server-to-server, where there is no browser session in which to present a cardholder challenge. Preczn therefore tells Stripe to fail the payment attempt rather than pause it if the card needs one. A card that requires 3D Secure authentication fails immediately, carrying Stripe's explanation, instead of waiting on a challenge that has nowhere to be shown.

Idempotency and Retries

Preczn sends an idempotency key to Stripe on every sale, auth, capture, void, and refund. If your request carried an idempotency key, that key is forwarded; otherwise Preczn uses the Preczn transaction id, which is unique per transaction.

This means a request that times out or fails in transit does not create a duplicate charge at Stripe — a resend with the same key returns the original result rather than charging again.

If Stripe reports that the same idempotency key is still in flight, Preczn waits and retries the payment intent up to three times. If it is still in flight after that, the transaction is recorded as P (Pending) rather than being duplicated, and resolves when Stripe reports the outcome.

Pending Transactions

A Stripe transaction can return with a status of P (Pending) and settle to A (Approved) or D (Declined) later. Three cases produce it:

  • A refund Stripe has accepted but not yet confirmed. Common, and it resolves on its own.
  • An authorization Stripe is still processing. The outcome arrives on the payment intent shortly afterward.
  • An idempotency key still in flight at Stripe. Preczn records Pending rather than risking a duplicate — see Idempotency and Retries.

Treat P as "not yet an outcome" — do not fulfill an order on it. Subscribe to the transaction.approved, transaction.declined, and transaction.errored webhook events to be notified when the transaction reaches its final status, or poll Get Transaction.

Data Sent to Stripe

Preczn passes these through to Stripe:

Preczn fieldAt Stripe
MetadataPayment intent and refund metadata, alongside precznId. Each value is truncated to 500 characters
descriptionPayment intent description, truncated to 350 characters
Dynamic Statement DescriptorStatement descriptor suffix, appended to the merchant's Stripe statement descriptor
Billing address, email, and cardholder namePayment method billing details, used for AVS
currencyPayment intent currency

Level II and Level III data have no equivalent on Stripe's payment intent, so those values are stored and reported by Preczn but are not transmitted to Stripe.

Transaction Status Mapping

Preczn maps each Stripe object status to a transaction status of A, D, P, or E.

Sale and Auth

Stripe payment intent statusTransactionPreczn statusWhat it means
succeededSaleA ApprovedAuthorized and captured
requires_captureAuthA ApprovedAuthorization hold placed
processingAuthP PendingStill in flight; resolves later
Any other statusSale, AuthD DeclinedNot approved

Capture and Void

Stripe payment intent statusTransactionPreczn statusWhat it means
succeededCaptureA ApprovedFunds captured
canceledVoidA ApprovedVoid succeeded — not a decline
Any other statusCapture, VoidD DeclinedThe operation did not complete

Refund

Stripe refund statusPreczn statusWhat it means
succeededA ApprovedFunds returned
pendingP PendingSubmitted; Stripe confirms the outcome later
Any other statusD DeclinedThe refund was not processed

Errors

A status of E (Error) always means the request itself failed — never an issuer decision. A card decline from Stripe is reported as D with Stripe's own decline message and decline code.

SituationPreczn statusMessage
Card declined by the issuerD DeclinedStripe's decline message, with the decline code
Stripe rejected the requestE ErrorStripe's own explanation of what was wrong with the request
Too many requests in a short windowE ErrorToo many requests made to the API too quickly
Stripe internal errorE ErrorAn error occurred internally with Stripe's API
Network failure reaching StripeE ErrorSome kind of error occurred during the HTTPS communication
Stripe rejected the API keyE ErrorYou probably used an incorrect API key
Anything elseE ErrorStripe Unexpected Error

You probably used an incorrect API key on a merchant that used to work usually means the key was rolled or revoked in the merchant's Stripe dashboard. Re-enter it on the merchant's Stripe connection.

Webhooks

Stripe webhooks are configured for you. When a merchant's Stripe keys are saved, Preczn registers its own webhook endpoint on that merchant's Stripe account and subscribes it to the events it needs:

  • payment_intent.succeeded
  • payment_intent.payment_failed
  • payment_intent.canceled
  • charge.refunded
  • charge.refund.updated

Preczn uses these to move a transaction off P (Pending) once Stripe reaches an outcome, and to reflect a refund that settles after the fact. Each merchant gets their own endpoint, on their own Stripe account. If the endpoint is later disabled or its event list edited in Stripe, Preczn restores it the next time the merchant's credentials are saved. Removing the connection deletes the endpoint from the merchant's Stripe account.

To receive transaction updates in your own application, subscribe to Preczn's transaction webhooks rather than to Stripe's.

Importing Existing Stripe Transactions

Enabling Import Merchant Transaction History on the Stripe connection lets Preczn pull a merchant's existing Stripe transactions into the Preczn vault, which is how you carry a merchant's processing history with them when boarding to another connection that requires it. The import covers the previous six months by default, and reads from each merchant's own Stripe account using their keys.

This is a one-time import. See Transaction Import for the full picture.

Testing in the Sandbox

  1. Add the merchant's sk_test_ and pk_test_ keys to a Test Mode merchant's Stripe connection.
  2. Send transactions using the standard Preczn test cards — Preczn translates them to Stripe's test card numbers automatically, so no Stripe-specific test data is needed.

Test and Live merchants hold separate keys, and Stripe routes to the matching environment based on the key the transaction runs with.

FAQ

Does each merchant need their own Stripe account?

Yes. Stripe is a direct connection: it processes on the merchant's own Stripe account, using keys the merchant provides. There is no platform-level Stripe key, and Preczn does not open Stripe accounts. If you want to create and manage merchant accounts under your own Stripe platform instead, use Stripe Connect.

The connection verified, but every transaction errors. Why?

The most common cause is that the merchant's Stripe account does not have raw card data APIs enabled. Verification only reads the account, which any working key can do — sending a card number is a separate permission Stripe grants on request. See Before You Start: Raw Card Data Access.

Card transactions work, but Apple Pay and Google Pay fail. Why?

Wallets need their own feature enabled on the Stripe account. Raw card data access lets Preczn send a card number; sending a decrypted wallet payload — the network token and cryptogram — is a separate permission. Ask Stripe Support to enable the decrypted tokens feature on PaymentIntents and SetupIntents. See Wallets.

Why was my connection rejected when the keys are correct?

Check that the key prefix matches the mode of the merchant. A Test Mode merchant only accepts sk_test_ and pk_test_ keys; a Live merchant only accepts sk_live_ and pk_live_. Stripe identifies the environment purely from the key, so Preczn rejects a mismatched pair before saving rather than transacting in the wrong environment.

If the prefixes are right and verification still fails, the key is most likely a restricted key that cannot read its own account. See Restricted keys.

Can I send ACH payments to Stripe?

No. Stripe is a card-only connection in Preczn, and an ACH transaction is never routed to it — a plan containing Stripe sends ACH to an ACH-capable connection instead. See ACH (Direct Debit) for the connections that do support it.

Why can't I void a sale?

A Stripe sale is captured at the moment it is approved, and Stripe cannot cancel a captured payment. Refund the sale instead. The same applies to an authorization you have already captured — Preczn rejects that void with Auth already captured. Use refund instead.

My transaction came back Pending. What do I do?

Wait for the final status; don't treat Pending as an approval. Stripe confirms some transactions asynchronously, and Preczn updates the transaction when Stripe's webhook reports the outcome. Subscribe to the transaction.approved, transaction.declined, and transaction.errored webhook events, or poll Get Transaction. A refund that returns Pending is normal — Stripe confirms it once the return clears.

A transaction timed out. Is it safe to retry?

Yes, as long as you resend the same idempotency key. Preczn sends an idempotency key to Stripe on every write, so a retry with the same key returns the original result instead of charging the cardholder twice. If you did not supply a key, Preczn used the Preczn transaction id — which means a brand-new transaction is a brand-new key, so check the transaction in Stripe before resubmitting.

Why did my card get declined for 3D Secure?

Preczn authorizes server-to-server, so there is no browser session in which to present a 3D Secure challenge. Rather than leave the transaction hanging in a state nobody can resolve, Stripe is instructed to fail the attempt outright. Cards that require a challenge on every transaction cannot be processed this way.

Can I run a zero-dollar verification to validate a card?

Yes. Verify is supported on Stripe — it validates the card with the issuer without moving funds and returns AVS and CVV results. Read those results rather than the status alone: Verify reports Approved whenever Stripe accepts the request, so an address or CVV mismatch shows up in the AVS and CVV values, not in the transaction status.

Do I need to configure webhooks in Stripe?

No. Preczn registers and maintains its own webhook endpoint on each merchant's Stripe account when their credentials are saved. Leave that endpoint alone in the Stripe dashboard; if it is disabled or altered, saving the merchant's Stripe connection again restores it. To receive updates in your own systems, use Preczn webhooks.

Will Level II or Level III data reach Stripe?

No. Stripe's payment intent has no equivalent fields, so Level II and Level III data submitted to Preczn are stored and reported by Preczn but not transmitted to Stripe. Metadata, descriptions, and statement descriptors do reach Stripe — see Data Sent to Stripe.


Did this page help you?