/redeem_sila

Initiates an ACH Credit transaction to a linked bank account from a Sila wallet.

This is the reverse process of /issue_sila; funds are removed from the provided wallet or virtual account, then the process of initiating an ACH Credit transaction to the linked bank account is started.

Initiates an ACH Debit transaction from an external source and issues those funds into a Sila wallet.

🚧

To be deprecated

/issue, /redeem, and /transfer will, in the long-term, be deprecated in favor of our /transact endpoint. We have no current date set for that deprecation, and we will continue supporting existing use of these endpoints until all customers can implement /transact.

We no longer make use of the Ethereum blockchain or the Sila stablecoin. All transactions are carried out immediately in USD.

Please implement /transact for all transaction types.

📘

Transaction Amount in Decimal Units

Please be aware that the amount value for this endpoint is in decimal units.

EX:

Transaction for $10 USD

/transact amount value = 1000

If the bank account cannot be credited (for instance, if the account has been closed), this operation will roll back funds to the provided wallet or virtual account.

Requests

The request body at this endpoint is the redeem_msg JSON object.

📘

/redeem timing

In SANDBOX, redeeming funds can take up to five minutes.

In PROD, redeeming funds will take a few business days, depending on when the request is issued. Read more about ACH timing here.

You can check the status of a transaction using the /get_transactions endpoint. You can also use webhooks to receive a notification when a transaction status is updated.

The optional account_name field is the name of the handle's linked account to credit the equivalent dollar amount.

The optional descriptor field is a 100-character field used to describe the transaction on the end-user’s bank statement.

The optional business_uuid field identifies a business which has an approved "ACH name".

The optional processing_type field allows specifying either "STANDARD_ACH"to use the standard ACH schedule or "SAME_DAY_ACH" to use the Same Day ACH schedule; by default, standard ACH will be used. See the ACH Processing Schedule for more details about the differences between standard ACH and Same Day ACH schedules.

Authorization / Authentication

Apps using Access Token Authorization

Use a valid access token in an Authorization: Bearer request header.

See Authenticating with an Access Token for more details.

Apps using ECDSA Authentication

Both authsignature and usersignature headers are required for this request. The usersignature header should be generated with a keypair registered to the user (either registered from the /register endpoint or the /register_wallet endpoint).

See the section on ECDSA Authentication for more detail about ECDSA signature generation.

Note - We recently renamed the field auth_handle to app_handle. For backward compatibility, auth_handle is still valid but has been removed from our documentation.

👍

/redeem_sila - The Unhappy Path

In sandbox: you can send an amount ending in 420 (e.g. 1420, 35420, 420) to simulate an ACH return.

POST /0.2/redeem_sila HTTP/1.1
sandbox.silamoney.com
Content-Type: application/json
// if using OAuth2
Authorization: Bearer [GENERATED JWT TOKEN HERE]
// if using ECDSA
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
usersignature: [GENERATED USERSIGNATURE HEX STRING HERE]

{
  "header": {
    "created": 1234567890, 
    "app_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "reference": "<your unique id>"
  }, 
  "amount": 1000,
  "account_name": "default",
  "descriptor": "optional transaction descriptor",
  "business_uuid": "UUID of a business with an approved ACH name",
  "processing_type": "STANDARD_ACH",
  "transaction_idempotency_id": "<UUID to uniquely identify a transaction for idempotency>",
  //For OAuth2
  "source_id": "<ID to uniquely identify which Sila wallet to pull funds from>",
  "destination_id": "<ID to uniquely identify which bank account to send funds to>"
}

***

HTTP/1.1 200 OK

{
  "reference": "<your unique id>",
  "message": "Transaction submitted to the processing queue.",
  "success": true,
  "status": "SUCCESS",
  "response_time_ms": "171", 
  "transaction_id": "UUID of the submitted transaction",
  "descriptor": "optional descriptor for the transaction"
}
const res = await Sila.redeemSila(
  amount,
  userHandle,
  walletPrivateKey,
  accountName,
  descriptor,
  businessUuid,
  processingType,
  cardName,
  sourceId,
  destinationId,
  mockWireAccountName, // optional
  transactionIdempotencyId, //optional
);
/*
Account Name is optional, OR "cardName": "your card name", never both. (defaults to 'default')
Descriptor is optional and sets the transaction description
BusinessUuid is optional and sets the ACH Name of the transaction
ProcessingType is optional and can be one of STANDARD_ACH or SAME_DAY_ACH or CARD (In case of card transaction)
Card Name is Optional, OR "accountName": "default", never both.
sourceId: source account id to debit from (optional)
destinationId : destination account id for credit (optional)
mockWireAccountName : Optional field for mock wire transaction (processingType = WIRE) test purpose
transactionIdempotencyId: UUID to uniquely identify a transaction for idempotency (optional)

*/

// Success Response Object

console.log(res.statusCode); // 200
console.log(res.data.reference); // Random reference number
console.log(res.data.success); // true
console.log(res.data.status); // SUCCESS
console.log(res.data.message); // Transaction submitted to processing queue
console.log(res.data.descriptor); // The transaction description set by you or blank if not set
console.log(res.data.transaction_id); // The transaction id
payload={
        "amount": 100000000000000000000000,                                        
        "user_handle":   "user.silamoney.eth",
        "descriptor": "Transaction Descriptor",
        "business_uuid": "UUID of a business with an approved ACH name",
        "account_name": "account name", # Either account_name or card_name or destination_id
        "card_name": "card name", # Either account_name or card_name or destination_id
        "destination_id": "-782bbd8c-ae27-4fb6-89e8-2675a1791382", # Either account_name or card_name or destination_id
        "source_id": "782bbd8c-ae27-4fb6-89e8-2675a1791382", # Optional
        "processing_type": ProcessingTypes # Optional: .STANDARD_ACH or .SAME_DAY_ACH or CARD or WIRE
        "mock_wire_account_name": "mock_account_success", # Optional
        "transaction_idempotency_id" : "<UUID to uniquely identify the transaction to prevent duplication>" #Optional
      }

Transaction.redeemSila(silaApp,payload,user_private_key)                              

### Success Response Object
{
  reference: "ref",
  message: "Transaction submitted to the processing queue.",
  success: True,
  status: "SUCCESS",
  transaction_id: "UUID of the submitted transaction",
  descriptor: "optional transaction descriptor",
  status_code: 200
}

### Failure Response Object
{
    status: 'FAILURE'
}
AccountTransactionMessage redeemMsg = AccountTransactionMessage.builder()
    .userHandle("user_handle")
    .userPrivateKey("user_private_key")
    .amount(100)
    .accountName("your_account_name")
    .descriptor("your custom descriptor") // Optional
    .businessUuid("some-business-uuid") // Optional
    .processingType(ProcessingTypeEnum.SAME_DAY) // Optional - SAME_DAY/STANDARD/INSTANT_ACH/CARD/WIRE
    .sourceId("source account id") // Optional
    .destinationId("destination account id") // Optional
    .mockWireAccountName("mock_account_success") // Optional mock_account_success/mock_account_fail
    .transactionIdempotencyId("UUID to uniquely identify the transaction to prevent duplication") // Optional
    .build();
ApiResponse response = api.RedeemSila(redeemMsg);

// Success response
System.out.println(response.getStatusCode()); // 200
TransactionResponse parsedResponse = (TransactionResponse) response.getData();
System.out.println(parsedResponse.getReference()); // Random reference number
System.out.println(parsedResponse.isSuccess()); // true
System.out.println(parsedResponse.getStatus()); // SUCCESS
System.out.println(parsedResponse.getMessage()); // Transaction submitted to processing queue.
System.out.println(parsedResponse.getTransactionId()); // Transaction id
System.out.println(parsedResponse.getDescriptor()); // The transaction descriptor (if was set)
use Silamoney\Client\Domain\AchType;

// Load your information
$userHandle = 'user.silamoney.eth';
$amount = 1000;
$accountName = 'Custom Account Name';
$userPrivateKey = 'some private key'; // Hex format
$descriptor = 'Transaction Descriptor'; // optional
$businessUuid = 'you-business-uuid-code'; // optional
$processingType = AchType::SAME_DAY(); // Optional. Supported values are STANDARD (default if not set), SAME_DAY, INSTANT, CARD, INSTANT_SETTLEMENT & WIRE.
$cardName = null;
$sourceId = "source id";
$destinationId = "destination id";
$mockWireAccountName = null; // Optional
$transactionIdempotencyId = "UUID"; // Optional

// Call the api
$response = $client->redeemSila($userHandle, $amount, $accountName, $userPrivateKey, $descriptor, $businessUuid, $processingType, $cardName, $sourceId, $destinationId, $mockWireAccountName, $transactionIdempotencyId);

//Success 200
echo $response->getStatusCode(); // 200
echo $response->getData()->getReference(); // Random reference number
echo $response->getData()->getStatus(); // SUCCESS
echo $response->getData()->getMessage(); // Transaction submitted to processing queue.
echo $response->getData()->getDescriptor(); // Transaction Descriptor.
echo $response->getData()->getTransactionId(); // The transaction id.
string userHandle = "your-user-handle";
int amount = 1000;
string walletPrivateKey = "0x...";
string accountName = "your_account_nickname"; // optional
string descriptor = "optional transaction descriptor"; // optional
string businessUuid = "UUID of a business with an approved ACH name"; // optional
ProcessingType processingType = ProcessingType.Wire; // optional - Sameday/Card/InstantACH/Standard/InstantSettlement/Wire
string mockWireAccountName = "mock_account_success"; // optional mock_account_success/mock_account_fail


string cardName = "your_cardName"; // optional
string sourceId = "UUID of virtual account - represents the source - NEW!";  // optional
string destinationId = "UUID of virtual account - represents the destination - NEW!"; // optional
string transactionIdempotencyId = "136e0996-c9e2-4f17-99ff-5cb3a3120dd2"; // optional

ApiResponse<object> response = api.RedeemSila(userHandle, amount, walletPrivateKey, accountName, descriptor, businessUuid, processingType, cardName, sourceId, destinationId, mockWireAccountName, transactionIdempotencyId);

// Success Object Response

Console.WriteLine(response.StatusCode); // 200
Console.WriteLine(((TransactionResponse)response.Data).Reference); // Random reference number
Console.WriteLine(((TransactionResponse)response.Data).Status); // SUCCESS
Console.WriteLine(((TransactionResponse)response.Data).Message); // Transaction submitted to processing queue.
Console.WriteLine(((TransactionResponse)response.Data).Descriptor); // Transaction descriptor.
Console.WriteLine(((TransactionResponse)response.Data).TransactionId); // Transaction id.
Console.WriteLine(((TransactionResponse)response.Data).Success); // true.
Console.WriteLine(((TransactionResponse)response.Data).ResponseTimeMs); // API responses time

📘

Descriptors

Currently only the first 10 characters of the 100-character descriptor field will appear on the customer's statement. Default values are Debit or Credit and do not carry a surcharge. The use of a descriptor will incur an additional fee per transaction.

📘

ACH

This is a 16 character field that appears on the end-user’s bank statement and reflects the company name responsible for the transaction. There is an additional application fee and process to approve the use of the company name.

KeyTypeDescription
headerJSON objectRequired. Requires these keys in JSON format: created, app_handle, user_handle. See the /check_handle endpoint for the complete list of fields in this object.
amountIntegerRequired. Min Length 1, Max digits 35
Example: 1000
Max value: 10000000
To increase, contact Sila
account_nameStringOptional. Max Length 40 Example: default.
descriptorStringOptional. Max Length 100
Example: transaction descriptor
business_uuidStringOptional. UUID of a business with an approved ACH name. The format should be a UUID string.
Example: 5167160d-9d12-4fa8-a8cd-302507782de0
processing_typeStringOptional. Choice field.
Examples: STANDARD_ACH or SAME_DAY_ACH
source_idStringFor ECDSA:
Optional. Payment method ID that is the source of funds. These can be viewed using /get_payment_methods. If not provided, the wallet in the usersignature of the header will be debited.

For OAuth2:
Required. Valid values for this field can be viewed using /get_payment_methods, which will return a "ledger_account_id".
destination_idStringFor ECDSA:
Optional. Payment method ID that is the destination of the funds. This can be used as an alternative to account_name

For OAuth2:
Required. ID that is the source of funds. Valid values for this field can be viewed using /get_payment_methods and looking for the bank_account_id value.
transaction_idempotency_idStringOptional. UUID to uniquely identify the transaction to make it idempotent. If transaction is submitted multiple times with the same transaction_idempotency_id it will only be processed once.

For ECDSA:
There are several valid combinations of optional parameters (account_name, source_id, destination_id) that can be used to identify the source and destination that will be used for the transaction. Below is that list:

  • account_name - for this, the destination will be the linked bank account with that account name, and the source will be the end users wallet as inferred from the user signature.
  • source_id, destination_id - for this, the source will explicitly be the payment method specified with source_id, and the destination will explicitly be the payment method specified with the destination_id.

For OAuth2:
destination_id and source_id are required.

Responses

Status Codesuccess AttributeDescription
200trueRedemption process started.
400falseBad request format - check validation_details for more information.
401falseauthsignature or usersignature header was absent or incorrect.

For transaction statuses, see: https://docs.silamoney.com/docs/redeem-status-diagram


What’s Next

The following is supporting documentation for /redeem_sila.