> ## Documentation Index
> Fetch the complete documentation index at: https://developers.orchestrasolutions.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Result Handling

> Parse and validate payment results from all payment methods.

<Info>
  This page is part of the **Payments Library Guides**. Prefer direct API calls instead? See [REST API Guides](/guides/rest-api/charge).
</Info>

**Prerequisites:** Complete the [Library Setup](/guides/library/setup) first.

All payment methods return results through the same callback function. This page covers how to parse results, check for success, and handle different payment types.

## Parsing Results

Use `parseResultToken()` to decode the result token:

```javascript theme={null}
function handleResult(result) {
  // User cancelled
  if (!result) {
    console.log('Payment cancelled');
    return;
  }

  const [data, success] = engine.parseResultToken(result.token);
  console.log('Payment result:', data);
}
```

The method returns a tuple:

* `data` - The parsed result object
* `success` - Boolean indicating if the token was decoded (not whether payment succeeded)

## Checking Payment Success

Always check `clientSuccess` first:

```javascript theme={null}
if (!data.clientSuccess) {
  console.error('Payment failed:', data.clientErrorMessage);
  return;
}

// Payment succeeded - check result type
```

## Result Types

Results vary based on the payment method used:

### PSP Results (CardPay, Apple Pay, Google Pay)

Card-based payments return results through `upgChargeResults`:

```javascript theme={null}
if (data.upgChargeResults) {
  const charge = data.upgChargeResults;

  if (charge.operationResultCode === 'Success') {
    console.log('Payment approved');
    console.log('Gateway:', charge.gatewayName);
    console.log('Reference:', charge.gatewayReference);
    console.log('Auth code:', charge.authorizationCode);
    console.log('Amount:', charge.amount, charge.currency);
  } else {
    console.log('Payment declined:', charge.operationResultDescription);
  }
}
```

**Available fields:**

| Field                        | Description                                                                             |
| ---------------------------- | --------------------------------------------------------------------------------------- |
| `gatewayName`                | Name of the payment gateway                                                             |
| `gatewayReference`           | Gateway's transaction reference                                                         |
| `authorizationCode`          | Authorization code from issuer                                                          |
| `amount`                     | Charged amount                                                                          |
| `currency`                   | Currency code                                                                           |
| `operationResultCode`        | `Success`, `Accepted`, `Rejected`, `TemporaryFailure`, `FatalFailure`, `NotImplemented` |
| `operationResultDescription` | Human-readable result message                                                           |
| `gatewayResultDescription`   | Message from the gateway                                                                |

### Direct Results (PayPal, BankPay, UPI)

Redirect-based payments return results through `directChargeResults`:

```javascript theme={null}
if (data.directChargeResults) {
  if (data.directChargeResults.success) {
    console.log('Payment successful');
  } else {
    console.log('Payment failed:', data.directChargeResults.message);
  }
}
```

### Tokenization Results

When using `TOKENIZE`, `CHARGE_AND_TOKENIZE`, or `PREAUTH_AND_TOKENIZE`, card details are returned in `tokenAndMaskedCardModel`:

```javascript theme={null}
if (data.tokenAndMaskedCardModel) {
  const tokenData = data.tokenAndMaskedCardModel;
  console.log('Token:', tokenData.token);
  console.log('Card type:', tokenData.bankCard.type);
  console.log('Masked number:', tokenData.bankCard.number);
  console.log('Expires:', tokenData.bankCard.expirationMonth + '/' + tokenData.bankCard.expirationYear);
  console.log('Name:', tokenData.bankCard.nameOnCard);
}
```

## Complete Example

```javascript theme={null}
async function handleResult(result) {
  // User cancelled
  if (!result) {
    showMessage('Payment cancelled', 'info');
    return;
  }

  const [data] = engine.parseResultToken(result.token);

  // Check overall success
  if (!data.clientSuccess) {
    showMessage('Payment failed: ' + data.clientErrorMessage, 'error');
    return;
  }

  // Handle PSP results (CardPay, Apple Pay, Google Pay)
  if (data.upgChargeResults) {
    if (data.upgChargeResults.operationResultCode === 'Success') {
      showMessage('Payment successful! Reference: ' + data.upgChargeResults.gatewayReference, 'success');
    } else {
      showMessage('Payment declined: ' + data.upgChargeResults.operationResultDescription, 'error');
    }
  }

  // Handle direct results (PayPal, BankPay, UPI)
  if (data.directChargeResults) {
    if (data.directChargeResults.success) {
      showMessage('Payment successful!', 'success');
    } else {
      showMessage('Payment failed: ' + data.directChargeResults.message, 'error');
    }
  }

  // Server-side validation (recommended)
  await validateWithServer(result.token);
}
```

## Server-Side Validation

Always validate results on your server before fulfilling orders:

```javascript theme={null}
// Client-side
async function validateWithServer(resultToken) {
  const response = await fetch('/api/validate-payment', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ resultToken })
  });

  const validation = await response.json();
  console.log('Server validation:', validation);
}
```

<CodeGroup>
  ```javascript Node.js theme={null}
  app.post('/api/validate-payment', async (req, res) => {
    const { resultToken } = req.body;

    const response = await fetch('https://api.orchestrasolutions.com/EWalletOperations/validateResults', {
      method: 'POST',
      headers: {
        'X-Api-Key': process.env.ORCHESTRA_API_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(resultToken)
    });

    const validationResult = await response.json();

    if (validationResult.failedUpgChargeResults?.length) {
      res.json({ success: false, error: validationResult.failedUpgChargeResults[0].operationResultDescription });
    } else if (validationResult.upgChargeResults) {
      // Payment confirmed - fulfill the order
      res.json({ success: true });
    } else if (validationResult.directChargeResults) {
      res.json({
        success: validationResult.directChargeResults.success,
        error: validationResult.directChargeResults.message
      });
    } else if (validationResult.tokenAndMaskedCardModel) {
      res.json({ success: true });
    }
  });
  ```

  ```python Python theme={null}
  @app.route('/api/validate-payment', methods=['POST'])
  def validate_payment():
      data = request.json
      result_token = data['resultToken']

      response = requests.post(
          'https://api.orchestrasolutions.com/EWalletOperations/validateResults',
          headers={
              'X-Api-Key': os.environ['ORCHESTRA_API_KEY'],
              'Content-Type': 'application/json'
          },
          data=json.dumps(result_token)
      )

      validation_result = response.json()

      if validation_result.get('failedUpgChargeResults'):
          return jsonify({
              'success': False,
              'error': validation_result['failedUpgChargeResults'][0]['operationResultDescription']
          })
      elif validation_result.get('upgChargeResults'):
          # Payment confirmed - fulfill the order
          return jsonify({'success': True})
      elif validation_result.get('directChargeResults'):
          return jsonify({
              'success': validation_result['directChargeResults']['success'],
              'error': validation_result['directChargeResults'].get('message')
          })
      elif validation_result.get('tokenAndMaskedCardModel'):
          return jsonify({'success': True})
  ```
</CodeGroup>

## Getting Selected Payment Method

Use `getSelectedProviderName()` to know which payment method the customer used:

```javascript theme={null}
function handleResult(result) {
  const provider = engine.getSelectedProviderName();
  console.log('Customer paid with:', provider);
  // "CardPay", "ApplePay", "GooglePay", "PayPal", "BankPay", or "UPI"
}
```

## Related

<CardGroup cols={2}>
  <Card title="Library Reference" icon="book" href="/guides/library/reference">
    Full API reference
  </Card>

  <Card title="Complete Example" icon="code" href="/guides/library/complete-example">
    End-to-end integration
  </Card>

  <Card title="Start Session API" icon="code" href="/api-reference/ewalletoperations/start-an-ewallet-session">
    Create a session token
  </Card>

  <Card title="Validate Results API" icon="check" href="/api-reference/ewalletoperations/validate-operation-results">
    Server-side validation endpoint
  </Card>
</CardGroup>
