/issue_sila
Initiates an ACH Debit transaction from an external source and issues those funds into a Sila wallet.
The /issue_sila endpoint starts the ACH Debit transaction of an end user's linked bank account (or other payment instrument); once that transaction has officially settled, the funds will be issued to the end user's 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.
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
/issue amount value = 1000
For ECDSA, be aware that unless specified otherwise, the wallet to which funds are issued is the one used to generate the usersignature
header.
For OAuth2, you will need to specify the source_id and destination_id. Please see key chart below for more details.
/issue Timing
In SANDBOX, issuing funds can take up to five minutes.
In PROD, issuing funds will take a few business days, depending on when the request is sent. Read more about ACH timing here.
When issuing funds from a debit card (Checkout.com integration), funds are available almost immediately.
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.
Note for Debit Card issue transactions
As of February 2024, we have added support for Visa AFT. See more here.
Requests
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.
/issue_sila - The Unhappy Path
Standard and Same Day ACH: In the sandbox only, you can simulate an ACH return by sending any amount ending in 420, like 1420 ($14.20), 78420 ($784.20), or 420 ($4.20). This will always simulate an ACH return of type R01-Insufficient Funds
Sandbox business UUID
For the purposes of testing /issue_sila in the Sandbox environment, you can use the business_uuid:
a9f38290-ce34-42db-95ab-630ebba6084a
.
The account_name
field is the name of the handle's linked account from which to debit the equivalent dollar amount. DO NOT include if you are using your bank account as the source_id.
The source_id
field is the payment method ID that is the source of funds. Please see key chart below for more details.
The destination_id
field is the payment method ID that is the destination of the funds. Please see key chart below for more details.
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 "SAME_DAY_ACH"
to use the Same Day ACH schedule.
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 source will be the linked bank account with that account name, and the destination will be the end users wallet as inferred from the user signature.
- card_name - for this, the source will be the linked debit card with that card name, and the destination 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, source_id and destination_id are required.
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 name
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.
POST /0.2/issue_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 the transaction to prevent duplication>",
//if using OAuth2
"source_id": "<ID to uniquely identify which bank account to pull funds from>",
"destination_id": "<ID to uniquely identify which Sila wallet to send funds to>",
"card_name": "default_card"
}
***
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 transaction descriptor"
}
const res = await Sila.issueSila(
amount,
userHandle,
walletPrivateKey,
accountName,
descriptor,
businessUuid,
processingType,
cardName,
sourceId,
destinatiionId,
transactionIdempotencyId,
);
/*
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
Card Name is Optional, OR "accountName": "default", never both.
sourceId: source account id to debit from (optional)
destinationId : destination account id for credit (optional)
transactionIdempotencyId: UUID to uniquely identify the transaction to prevent duplication
*/
// 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 source_id
"card_name": "card name", # Either account_name or card_name or source_id
"source_id": "782bbd8c-ae27-4fb6-89e8-2675a1791382", # Either account_name or card_name or source_id
"destination_id": "-782bbd8c-ae27-4fb6-89e8-2675a1791382", # Optional
"processing_type": ProcessingTypes, # Optional: Either .STANDARD_ACH or .SAME_DAY_ACH or INSTANT_SETTLEMENT
"transaction_idempotency_id" : "<UUID to uniquely identify the transaction to prevent duplication>" # Optional
}
Transaction.issueSila(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 issueMsg = 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/INSTANT_SETTLEMENT
.sourceId("source account id") // Optional
.destinationId("destination account id") // Optional
.transactionIdempotencyId("UUID to uniquely identify the transaction to prevent duplication") // Optional
.build();
ApiResponse response = api.IssueSila(issueMsg);
// Success response
System.out.println(response.getStatusCode()); // 200
TransactionResponse parsedResponse = (TransactionResponse) response.getData();
System.out.println(parsedResponse.isSuccess());
System.out.println(parsedResponse.getReference()); // Random reference number
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. Currently supported values are STANDARD (default if not set) and SAME_DAY
$cardName = null;
$sourceId = "source id"; // optional
$destinationId = "destination id"; //optional;
$transactionIdempotencyId = "UUID"; //optional;
// Call the api
$response = $client->issueSila($userHandle, $amount, $accountName, $userPrivateKey, $descriptor, $businessUuid, $processingType, $cardName, $sourceId, $destinationId, $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
string transactionIdempotencyId = "136e0996-c9e2-4f17-99ff-5cb3a3120dd2"; // optional
ProcessingType processingType = ProcessingType.Sameday; // optional
string cardName = "your_card_name"; // optional
string sourceId = "UUID of virtual account - represents the source - NEW!"; // optional
string destinationId = "UUID of virtual account - represents the destination - NEW!"; // optional
ApiResponse<object> response = api.IssueSila(userHandle, amount, walletPrivateKey, accountName, descriptor, businessUuid, processingType, cardName, sourceId, destinationId, 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); // optional transaction descriptor
Console.WriteLine(((TransactionResponse)response.Data).TransactionId); // UUID of the submitted transaction
Console.WriteLine(((TransactionResponse)response.Data).ResponseTimeMs); // API responses time
Console.WriteLine(((TransactionResponse)response.Data).Success); // true
Key | Type | Description |
---|---|---|
header | JSON object | Required. 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. |
amount | Integer | Required. Min Length 1, Max digits 35 Example: 1000 Max value: 10000000 Please contact Sila to increase. |
account_name | String | Optional. Max Length 40. Name of the linked account to debit from that is the source of funds. DO NOT include if you are using your bank account as the source_id. Example: default |
descriptor | String | Optional. Max Length 100 Note that only the first 10 characters show on the resulting bank statement. Example: transaction descriptor |
business_uuid | String | Optional. UUID of a business with an approved ACH name. The format should be a UUID string. Example: 5167160d-9d12-4fa8-a8cd-302507782de0 |
processing_type | String | Optional. Choice field. Examples: STANDARD_ACH, SAME_DAY_ACH, INSTANT_SETTLEMENT, CARD_CKO |
source_id | String | For ECDSA: Optional. Payment method ID that is the source of funds. This can be used as an alternative to account_name. Valid values for this field can be viewed using /get_payment_methods and looking for the **_id value. Example: bank_account_id = 5167160d-9d12-4fa8-a8cd-302507782de0. For OAuth2: Optional. 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 or card_id value. |
destination_id | String | For ECDSA: Optional. Payment method ID that is the destination of the funds. If not provided, the wallet in the usersignature of the header will be credited. Valid values for this field can be viewed using /get_payment_methods and looking for the **_id value. Example: blockchain_address_id = 5167160d-9d12-4fa8-a8cd-302507782de0.For OAuth2: Optional. Valid values for this field can be viewed using /get_payment_methods, which will return a "ledger_account_id" that will be used as the destination_id. |
transaction_idempotency_id | String | Optional. 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. |
card_name | String | Optional. Max Length 40 Name of the linked card to debit from that is the source of funds. Example: default_card |
Responses
Status Code | success Attribute | Description | error_code |
---|---|---|---|
200 | true | Issuance process started. | Key not present in response. |
400 | false | Bad request format - check validation_details for more information. | Key not present in response. |
401 | false | authsignature or usersignature header was absent or incorrect. | Key not present in response. |
403 | false | Instant Settlement failure: Instant Settlement is disabled for the application being used | Key not present in response. |
403 | false | Instant Settlement failure: The transaction amount issued is more than minimum Reserve Wallet balance. | Key not present in response. |
403 | false | Instant Settlement failure: Application Reserve Wallet does not have sufficient balance, contact admin | Key not present in response. |
403 | false | Failure with message "Bank account is not supported for WEB debits." due to the linked bank account having a web_debit_verified value of false where the app is configured to use the WEB SEC Code. | Key not present in response. |
For transaction statuses, see: https://docs.silamoney.com/docs/issue-status-diagram
Updated about 2 months ago
The following is supporting documentation for /issue_sila.