Troubleshooting

Solutions to common issues and error messages.

Quick fixes for the most common integration issues, errors, and unexpected behaviors.

API errors

401 Unauthorized

Cause: Invalid or missing API key

Solutions:

  • Check that you're using the correct key (public for initialize, secret for verify)
  • Verify the key hasn't been revoked or rotated
  • Ensure the key is included in the Authorization header
# Correct format
Authorization: YOUR_API_KEY

400 Bad Request

Cause: Validation failed on required fields

Common fixes:

ErrorFix
"Amount is required"Include amount in the request body
"Invalid email"Ensure email format is valid
"Currency not supported"Use NGN or USD
"Reference already exists"Generate a unique reference for each transaction

404 Not Found

Cause: Transaction or endpoint doesn't exist

Solutions:

  • For verification: Check that the transRef is correct
  • For endpoints: Verify the URL path matches the documentation exactly

500 Internal Server Error

Cause: Something went wrong on our end

Solutions:

  • Retry the request after a few seconds
  • Check our status page for outages
  • Contact support if it persists

Payment issues

Payment initialization fails

Symptoms: API returns error when trying to initialize

Check:

  1. Is amount specified in lowest currency unit?

    Wrong: "amount": 150.00
    Correct: "amount": 15000

  2. Is email a valid email format?

  3. Are you using the public key (not secret key)?

  4. Is your account active and verified?

Debug code:

// Log the full error response
try {
  const response = await initializePayment(data);
} catch (error) {
  console.log('Status:', error.response.status);
  console.log('Message:', error.response.data.message);
  console.log('Errors:', error.response.data.errors);
}

Customer can't complete payment

Symptoms: Authorization URL loads but payment fails

Common causes:

IssueSolution
Card declinedTry a different card or payment method
Insufficient fundsCustomer needs to add funds or use different card
3DS authentication failsCustomer should contact their bank
Session expiredGenerate a new authorization URL
Unsupported card typeUse Visa, Mastercard, or Verve

Authorization URL not working

Symptoms: Link returns 404 or doesn't load

Check:

  • URL hasn't expired (valid for 24 hours)
  • No extra characters added to the URL
  • Customer has stable internet connection

Verification issues

Transaction not found during verification

Symptoms: 404 error when calling verify endpoint

Check:

  1. Are you using the correct transRef (not reference)?
  2. Is the transaction in the right environment?
    • Sandbox transactions can't be verified in production
  3. Wait 10-30 seconds after payment before verifying
// Use credoReference from initialization response
const transRef = initializeResponse.data.credoReference;
// NOT: const transRef = initializeResponse.data.reference;

Verification returns wrong status

Symptoms: Status shows failed but customer says they paid

Solutions:

  • Always rely on server-side verification, not client feedback
  • Check if webhook was received (more reliable than callback)
  • Allow 1-2 minutes for status to update
  • Contact support with transRef for investigation

Webhook issues

Webhooks not being received

Checklist:

  • URL is publicly accessible (not localhost)
  • URL uses HTTPS
  • Webhook is configured in the correct environment (sandbox vs production)
  • Firewall allows requests from Credo IPs
  • Endpoint responds with HTTP 200 within 5 seconds

Debug with webhook.site:

  1. Go to webhook.site
  2. Copy the unique URL
  3. Add it to your Credo dashboard
  4. Make a test payment
  5. Check if events appear on webhook.site

Only receiving some event types

Cause: Your handler only checks for transaction.successful

Credo sends 4 event types. Make sure you handle all the ones relevant to your integration:

EventWhen it fires
transaction.successfulPayment processed successfully
transaction.failedPayment declined or insufficient funds
transaction.transaction.transfer.reverseBank transfer amount mismatch — reversed to customer
transaction.settlement.successSettlement paid out to merchant

Duplicate webhook deliveries

Cause: Your endpoint didn't respond with 200 quickly enough

Solution:

  • Respond with HTTP 200 immediately
  • Process the event asynchronously
  • Implement idempotency checks using transRef + event as a composite key
app.post('/webhook', (req, res) => {
  // Respond immediately
  res.status(200).send('OK');

  // Process asynchronously
  processWebhook(req.body);
});

Webhook signature verification fails

Cause: Incorrect signature calculation

Correct formula (HMAC-SHA512 with your secret key):

const signature = crypto
  .createHmac('sha512', process.env.CREDO_SECRET_KEY)
  .update(JSON.stringify(payload))
  .digest('hex');

Check:

  • Using your secret key (not public key)
  • Payload isn't modified before verification (use the raw request body)
  • Using HMAC-SHA512 (not SHA-256 or plain SHA-512)
  • Comparing against the credo-signature header value

Settlement issues

Settlement not received

Check:

  1. Is it a business day? (No settlements on weekends/holidays)
  2. Was transaction before 12 PM? (After 12 PM settles next day)
  3. Is bank account verified and active?

Timeline:

Transaction timeSettlement time
Monday 10 AMMonday by 6 PM
Monday 3 PMTuesday by 6 PM
Friday 10 AMFriday by 6 PM
Friday 3 PMMonday by 6 PM

Settlement amount is wrong

Common causes:

ExpectedActualReason
₦10,000₦9,800Merchant bears fee (₦200 deducted)
₦10,000₦10,000Customer bears fee (no deduction)
Split configDifferent splitRules changed in dashboard

Check your fee bearer setting:

{
  "bearer": 0  // Customer pays fee
  "bearer": 1  // You pay fee
}

Mobile SDK issues

Flutter SDK: Payment modal not opening

Check:

  • flutter_webview_plugin is installed
  • Internet permission added to AndroidManifest.xml
  • iOS: NSAppTransportSecurity allows arbitrary loads (for development)

React Native SDK: "Cannot read property"

Check:

  • Ran cd ios && pod install after installation
  • Rebuilt the app after installing package
  • Imported from correct path

Testing issues

Test cards not working

Check:

  • Using sandbox environment (api.credodemo.com)
  • Using test public key (starts with 0PUB)
  • Card number entered correctly (no spaces)

Valid test cards:

CardNumberResult
Visa4012000033330026Success
MasterCard5555555555554444Success (no 3DS)

Callback URL not triggered

Check:

  • URL is publicly accessible
  • URL returns a valid response
  • No CORS issues (for web integrations)

Still having issues?

If none of these solutions work:

  1. Check our status page for outages
  2. Search our documentation for detailed guides
  3. Contact support with:
    • Transaction reference
    • Error messages
    • Timestamp of issue
    • Steps to reproduce

Was this page helpful?

Last updated on

On this page