Receipt Upload Testing

Magic Receipts QA Test API

Overview

The Magic Receipts QA Test API provides a way to test receipt upload functionality without requiring actual receipt processing. This allows for predictable, repeatable testing scenarios that can be used during development, QA testing, and integration testing.

How It Works

When you include specific offer IDs in your receipt upload request and set the isQA=true parameter, the API will return hardcoded responses instead of processing the receipt normally. This bypasses all the complex receipt validation logic and returns predictable results.

Quick Start

Basic Usage

  1. Include a QA test offer ID in your request
  2. Set the isQA=true parameter
  3. Submit your receipt upload request

Example Request

POST https://receipts.bitlabs.ai/api/receipt/upload 
Content-Type: multipart/form-data

# Form data:
isQA=true
offerIDs[]=7278401  # QA test offer ID for confirmed offers
receiptImage=<your_receipt_image>

Example Response

{
  "status": 200,
  "data": {
    "confirmed": {
      "offers": [
        {
          "addedToList": false,
          "award": "50 points",
          "awardCashback": "$0.50",
          "cashbackAmount": 0.5,
          "errorCode": 0,
          "errorStr": null,
          "imageUrl": "https://qa-test-images.com/test-receipt.jpg",
          "isBarcodeScanEligible": false,
          "isUnselectedOffer": false,
          "maxLinesForManualReview": 3,
          "offerID": 7278401,
          "offerTitle": "Test Product",
          "pendingDays": 0,
          "shortErrorStr": null,
          "state": "confirmed",
          "surveyUrl": null,
          "uploadOfferID": 7278401
        }
      ],
      "totalAward": "50 points",
      "totalAwardCashback": "$0.50"
    },
    "confirmedAndAwardPending": {
      "offers": [
        // Same offer as above
      ],
      "totalAward": "50 points",
      "totalAwardCashback": "$0.50"
    }
  }
}

Available Test Scenarios

1. Confirmed Offers (Offer ID: 7278401 or 999001)

What it simulates: Offers that are automatically approved and immediately credited.

Use case: Test successful receipt uploads and point crediting.

Response includes:

  • confirmed section with approved offers
  • confirmedAndAwardPending section (same offers)
  • Award amounts: 50 points ($0.50)
  • All production fields: addedToList, errorCode, errorStr, imageUrl, isBarcodeScanEligible, isUnselectedOffer, maxLinesForManualReview, offerTitle, pendingDays, shortErrorStr, surveyUrl, uploadOfferID

2. Rejected Offers (Offer ID: 999002)

What it simulates: Offers that are automatically rejected due to validation failures.

Use case: Test error handling and rejection scenarios.

Response includes:

  • rejected section with error details
  • Error messages: "We are unable to read the store name on your receipt. Please review your receipt to ensure it is complete and add additional photos if needed."
  • Short error: "Wrong Store"
  • Error code: 9
  • Award amounts: 0 points ($0.00)
  • All production fields matching actual API responses

3. Manual Review (Offer ID: 999003)

What it simulates: Offers that require manual review by an admin.

Use case: Test pending review scenarios.

Response includes:

  • pending section with offers awaiting review
  • Award amounts: 0 points ($0.00) until approved
  • All production fields with proper null values for error fields

4. Award Pending (Offer ID: 999004)

What it simulates: Offers that are approved but awards are pending for a specified number of days.

Use case: Test delayed award scenarios.

Response includes:

  • awardPending section with pending offers
  • confirmedAndAwardPending section
  • pendingDays: 7
  • Award amounts: 25 points ($0.25)
  • All production fields with proper pending day values

5. Mixed Status (Offer ID: 999005)

What it simulates: Receipts with multiple offers in different states.

Use case: Test complex scenarios with multiple offer types.

Response includes:

  • confirmed section: 30 points ($0.30)
  • awardPending section: 20 points ($0.20)
  • confirmedAndAwardPending section: 50 points ($0.50) total
  • All production fields for both offer types

6. Fraud Flagged (Offer ID: 999006)

What it simulates: Offers flagged for potential fraud requiring manual review.

Use case: Test fraud detection scenarios.

Response includes:

  • pending section with fraud-flagged offers
  • Award amounts: 0 points ($0.00) until reviewed
  • All production fields with proper pending state

7. Barcode Scanning Enabled (Offer ID: 999007)

What it simulates: Offers that are approved and have barcode scanning functionality enabled.

Use case: Test barcode scanning features.

Response includes:

  • confirmed section with approved offers
  • isBarcodeScanEligible: true
  • Award amounts: 40 points ($0.40)
  • All production fields with barcode scanning enabled

Complete Offer ID Reference

Offer IDScenarioResponse StructureAward Amount
7278401Confirmed Onlyconfirmed + confirmedAndAwardPending50 points
999001Confirmed Only (Alt)confirmed + confirmedAndAwardPending50 points
999002Rejectedrejected0 points
999003Manual Reviewpending0 points
999004Award PendingawardPending + confirmedAndAwardPending25 points
999005Mixed Statusconfirmed + awardPending + confirmedAndAwardPending30 + 20 points
999006Fraud Flaggedpending0 points
999007Barcode Enabledconfirmed + confirmedAndAwardPending40 points

Actual QA Test Offer Constants

The following are the actual constants from the QaTestOffers class that you can use in your code:

// Confirmed offers (successful uploads)
QaTestOffers.CONFIRMED_ONLY = 7278401
QaTestOffers.CONFIRMED_ONLY_ALT = 999001

// Error scenarios
QaTestOffers.REJECTED = 999002
QaTestOffers.MANUAL_REVIEW = 999003

// Award scenarios
QaTestOffers.AWARD_PENDING = 999004
QaTestOffers.MIXED_STATUS = 999005

// Special scenarios
QaTestOffers.FRAUD_FLAGGED = 999006
QaTestOffers.BARCODE_ENABLED = 999007

// All QA test offer IDs
QaTestOffers.ALL_QA_TEST_OFFER_IDS = [7278401, 999001, 999002, 999003, 999004, 999005, 999006, 999007]

Response Structure

All responses follow this structure and include only the fields that are actually returned in production API responses:

{
  "status": 200,
  "data": {
    "confirmed": { "offers": [...], "totalAward": "...", "totalAwardCashback": "..." },
    "rejected": { "offers": [...], "totalAward": "...", "totalAwardCashback": "..." },
    "pending": { "offers": [...], "totalAward": "...", "totalAwardCashback": "..." },
    "awardPending": { "offers": [...], "totalAward": "...", "totalAwardCashback": "..." },
    "confirmedAndAwardPending": { "offers": [...], "totalAward": "...", "totalAwardCashback": "..." },
    "manualReview": { "offers": [...], "totalAward": "...", "totalAwardCashback": "..." }
  }
}

Note: Only the relevant sections for each test scenario will be included in the response. Each offer object contains exactly the same fields as production responses, ensuring accurate testing.

Testing Best Practices

1. Test All Scenarios

Use each offer ID to test different response types and ensure your application handles them correctly.

2. Test Error Handling

Use the rejected offer ID (999002) to test how your application displays error messages.

3. Test UI States

Use different scenarios to test how your UI displays:

  • Loading states
  • Success messages
  • Error messages
  • Pending review notifications

4. Test Award Calculations

Use the mixed status scenario (999005) to test how your application handles multiple offers with different states.

5. Test Edge Cases

  • Use unknown offer IDs to test fallback behavior
  • Test with multiple QA offer IDs in the same request
  • Test with both QA and non-QA offer IDs

Integration Examples

JavaScript/TypeScript

async function testReceiptUpload() {
  const formData = new FormData();
  formData.append('isQA', 'true');
  formData.append('offerIDs[]', '7278401'); // Confirmed offers
  formData.append('receiptImage', receiptFile);

  const response = await fetch('https://receipts.bitlabs.ai/api/receipt/upload', {
    method: 'POST',
    body: formData
  });

  const result = await response.json();
  console.log('QA Test Response:', result);
}

Python

import requests

def test_receipt_upload():
    url = 'https://receipts.bitlabs.ai/api/receipt/upload'
    files = {'receiptImage': open('receipt.jpg', 'rb')}
    data = {
        'isQA': 'true',
        'offerIDs[]': '7278401'  # Confirmed offers
    }
    
    response = requests.post(url, files=files, data=data)
    result = response.json()
    print('QA Test Response:', result)

cURL

curl -X POST \
  -F "isQA=true" \
  -F "offerIDs[]=7278401" \
  -F "[email protected]" \
   https://receipts.bitlabs.ai/api/receipt/upload 

Troubleshooting

Common Issues

  1. No QA response received

    • Ensure isQA=true parameter is included
    • Verify you're using a valid QA test offer ID
    • Check that the offer ID is in the offerIDs[] array
  2. Unexpected response structure

    • Each scenario returns different sections
    • Only relevant sections are included
    • Check the offer ID mapping table above
  3. Multiple offer IDs

    • The first QA test offer ID found determines the response
    • Mixing QA and non-QA offer IDs works (QA takes precedence)

Debugging Tips

  1. Log the offer IDs being sent in your request
  2. Check the response status (should always be 200 for QA tests)
  3. Verify the response structure matches the expected format
  4. Test with different offer IDs to ensure variety

Support

For questions about the QA test API:

  • Check this documentation first
  • Review the offer ID reference table
  • Test with different scenarios to understand the behavior
  • Contact the development team for technical issues

Note: This QA test API is for testing purposes only. Do not use these offer IDs in production environments.