Contents

getChoicesForPayment#

Get the list of contract choices for a payment transaction in the dialog (confirmation) state, together with information on whether each choice can be paid with the funds available in the wallet, and whether a specific choice should be paid automatically without user confirmation, based on the user’s configuration or the type of payment requested.

For a contract v1 order, the choices array of the result mirrors the choices of the contract. For a contract v0 order, which has no choices, it contains a single choice with no inputs/outputs.

Request:

The args must be a GetChoicesForPaymentRequest object.

Response:

On success, the result is a GetChoicesForPaymentResult object.

Side effects:

None; this operation is a pure read. The payability of each choice is evaluated against the coin, exchange and token information already stored in the wallet database, without any network access.

Expected errors:

The caller can handle the following errors inline: WALLET_REQUEST_TRANSACTION_STATE_UNSUPPORTED, WALLET_TRANSACTION_NOT_FOUND, WALLET_CORE_API_BAD_REQUEST.

The WALLET_REQUEST_TRANSACTION_STATE_UNSUPPORTED error is returned while the contract terms of the payment have not been downloaded yet; the caller should wait for the corresponding transaction state transition and try again.

interface GetChoicesForPaymentRequest {
  // Transaction identifier of the payment.
  transactionId: string;

  // Force a particular coin selection when evaluating
  // whether the choices are payable.
  forcedCoinSel?: ForcedCoinSel;
}
interface ForcedCoinSel {
  coins: {
    value: AmountString;
    contribution: AmountString;
  }[];
}
type GetChoicesForPaymentResult = {
  // Details for all choices in the contract.
  //
  // The index in this array corresponds to the choice
  // index in the original contract v1.  For contract v0
  // orders, it will only contain a single choice with no
  // inputs/outputs.
  choices: ChoiceSelectionDetail[];

  // Index of the choice in the choices array to present
  // to the user as default.
  //
  // Won't be set if no default selection is configured
  // or no choice is payable; otherwise it will always
  // be 0 for v0 orders.
  defaultChoiceIndex?: number;

  // Whether the choice referenced by automaticExecutableIndex
  // should be confirmed automatically without user interaction.
  //
  // If true, the wallet should call confirmPay immediately
  // afterwards; if false, the user should first be prompted
  // to select and confirm a choice.  Undefined when no
  // choices are payable.
  automaticExecution?: boolean;

  // Index of the choice that would be set to automatically
  // execute if the choice was payable.  When automaticExecution
  // is set to true, the payment should be confirmed with this
  // choice index without user interaction.
  automaticExecutableIndex?: number;

  // Data extracted from the contract terms that
  // is relevant for payment processing in the wallet.
  contractTerms: MerchantContractTerms;
};
interface ChoiceSelectionDetailPaymentPossible {
  status: ChoiceSelectionDetailType.PaymentPossible;

  // Amount requested by the contract for this choice.
  amountRaw: AmountString;

  // Total cost of this choice for the wallet, including fees.
  amountEffective: AmountString;

  // Scope of the coins that would be spent, if known.
  scopeInfo: ScopeInfo | undefined;

  tokenDetails?: PaymentTokenAvailabilityDetails;
}
interface ChoiceSelectionDetailInsufficientBalance {
  status: ChoiceSelectionDetailType.InsufficientBalance;

  // Amount requested by the contract for this choice.
  amountRaw: AmountString;

  balanceDetails?: PaymentInsufficientBalanceDetails;
  tokenDetails?: PaymentTokenAvailabilityDetails;
}
type ChoiceSelectionDetailType =
  | "payment-possible"
  | "insufficient-balance";
interface PaymentTokenAvailabilityDetails {
  // Number of tokens requested by the merchant.
  tokensRequested: number;

  // Number of tokens available to use.
  tokensAvailable: number;

  // Legacy compatibility field.  Always zero: tokens from another
  // merchant are counted as untrusted and cannot be used.
  tokensUnexpected: number;

  // Number of tokens not issued by the receiving merchant.
  //
  // Cannot be used to pay, so an error should be displayed.
  tokensUntrusted: number;

  perTokenFamily: {
    [slug: string]: {
      causeHint?: TokenAvailabilityHint;
      requested: number;
      available: number;
      unexpected: number;
      untrusted: number;
    };
  };
}
type TokenAvailabilityHint =
  | "wallet-tokens-available-insufficient"
  | "merchant-unexpected"
  | "merchant-untrusted";