# Transfer

We provide the convenience of transferring funds directly to other accounts.

In the document below, we will detail the processes related to making transfers via Pix or Ted, providing a clear and comprehensive understanding of the operation and how to manage the lifecycle of this resource.

You can also use a Pix Key to send a Pix Transfer.

NOTE: Read Core Concepts before continuing this guide.

**RESOURCE SUMMARY**

TransferCreate Pix or Ted TransfersPix KeyLook up recipient data via Pix keys before creating transfers

## Setup

For each environment: (Sandbox or Production)

1. Create an account at Stark Bank.

2. Create a webhook with the following subscriptions to receive events in your desired URL:

transfer

2.1. Via Internet Banking: 

Integrations > Webhook > New Webhook

2.2. Via API: 

Use the POST /webhook route to create the webhook

## Transfer Overview

Transfer is a resource that can be used to send Pix and Ted payments to other bank accounts.

To create a Transfer (Ted or Pix), you need to provide the mandatory parameters: amount, name, taxId, bankCode, branchCode and accountNumber.

You can also send a Pix Transfer using a Pix Key and an amount.

Optional parameters include accountType, description, externalId, scheduled, tags, and rules.

### The Transfer Object

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `id` | STRING | Unique id for the transfer. |
| `amount` | INTEGER | Amount in cents to be transferred. Example: 1000000 (R$10,000.00). |
| `name` | STRING | Recipient full name. |
| `taxId` | STRING | Recipient CPF or CNPJ. |
| `bankCode` | STRING | 3-digit bank code (Ted) or 8-digit ISPB code (Pix) of the recipient's bank. |
| `branchCode` | STRING | Recipient's branch code. |
| `accountNumber` | STRING | Recipient's account number. |
| `accountType` | STRING | Recipient's bank account type. Options: "checking", "payment", "savings", "salary". Default: "checking". |
| `externalId` | STRING | Unique ID to prevent duplicate transfers. Repeated externalIds will cause failures. |
| `scheduled` | STRING | Scheduled date or datetime for the transfer. Example: "2020-08-14" or "2020-08-14T15:23:26+00:00". |
| `description` | STRING | Custom description to override the default bank statement description. |
| `tags` | LIST OF STRINGS | Tags associated with the transfer. |
| `rules` | LIST OF OBJECTS | List of rule objects with key and value to modify transfer behavior. |
| `fee` | INTEGER | Fee charged in cents. |
| `status` | STRING | Current transfer status. Options: "created", "processing", "success", "failed", "canceled". |
| `transactionIds` | LIST OF STRINGS | Ledger transaction IDs linked to the transfer. |
| `created` | STRING | Creation datetime. Example: "2020-02-06T16:22:24.664148+00:00". |
| `updated` | STRING | Last update datetime. Example: "2020-02-06T16:22:24.664148+00:00". |

### The Transfer Status

Each Transfer has a status that can change over time according to its life cycle:

| Status | Description |
| --- | --- |
| Created | The Transfer was successfully created in Stark Bank. |
| Processing | The Transfer is being processed by Stark Bank. |
| Success | The Transfer was successfully completed. |
| Failed | The Transfer was unsuccessful. |
| Canceled | The Transfer was canceled before processing. |

### The Transfer Logs

Every time either you or Stark Bank makes a change to a Transfer, we create a Log. Logs are pretty useful for understanding the life cycle of each Transfer and the changes that happened to it. Here you can see the flow of possible logs:

A completed Transfer can be reversed back to its payer. When a reversal occurs, the following flow of logs will happen:

| Log type | Status | Description |
| --- | --- | --- |
| Created | Created | The Transfer was successfully created in Stark Bank. |
| Sending | Processing | The Transfer is being sent to the banking network. |
| Sent | Processing | The Transfer was sent to the banking network. |
| Success | Success | The Transfer was successfully completed and credited. |
| Failed | Failed | The Transfer was unsuccessful. |
| Resending | Processing | The Transfer is being retried after a temporary failure. |
| Canceling | Processing | The Transfer cancellation is being processed. |
| Canceled | Canceled | The Transfer was canceled before processing. |
| Reversing | Success | The Transfer reversal is being processed. |
| Reversed | Success | The Transfer was reversed back to the payer. |
| Refunded | Success | The Transfer was refunded. |

### Creating Ted Transfers

To create a Ted Transfer, fill in the mandatory parameters: amount, name, taxId, bankCode, branchCode and accountNumber.

For Ted Transfers, the bankCode parameter must be filled with the 3-digit bank code of the recipient's bank.

Ted Transfers scheduled for today will be accepted until 16:00 (BRT) and will be pushed to the next business day afterwards.

**Request**

```python
import starkbank

transfers = starkbank.transfer.create([
    starkbank.Transfer(
        amount=1000000,
        tax_id="123.456.789-10",
        name="Daenerys Targaryen Stormborn",
        bank_code="665",
        branch_code="2201",
        account_number="76543-8"
    )
])

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=1000000,
    bank_code=665,
    branch_code=2201,
    created=2020-02-06 16:22:24.664134,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=0,
    id=5412038532661248,
    name=Daenerys Targaryen Stormborn,
    rules=[],
    scheduled=2020-08-14 10:00:00,
    status=created,
    tags=[],
    tax_id=123.456.789-10,
    transaction_ids=[],
    updated=2020-02-06 16:22:24.664148
)
```

### Creating Pix Transfers

To create a Pix Transfer, fill in the mandatory parameters: amount, name, taxId, bankCode, branchCode and accountNumber.

For Pix Transfers, the bankCode parameter must be filled with the 8-digit ISPB code of the recipient's bank.

Pix Transfers are available 24/7 and can be scheduled for any date and time.

**Request**

```python
import starkbank

transfers = starkbank.transfer.create([
    starkbank.Transfer(
        amount=1000000,
        tax_id="123.456.789-10",
        name="Daenerys Targaryen Stormborn",
        bank_code="20018183",
        branch_code="2201",
        account_number="76543-8"
    )
])

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=1000000,
    bank_code=20018183,
    branch_code=2201,
    created=2020-02-06 16:22:24.664134,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=0,
    id=5412038532661248,
    name=Daenerys Targaryen Stormborn,
    rules=[],
    scheduled=2020-08-14 10:00:00,
    status=created,
    tags=[],
    tax_id=123.456.789-10,
    transaction_ids=[],
    updated=2020-02-06 16:22:24.664148
)
```

### Creating Transfers with accountType, rules parameters

AccountType: You can use this parameter to set the receiver's bank account type. Options include "checking", "payment", "savings", and "salary". "checking" is the default.

This parameter only takes effect for Pix Transfers.

The transfer will fail if the accountType is different from the receiver's bank account.

Rules: This parameter can be used to modify the transfer behavior.

The following rules are available:

resendingLimit: integer value that sets the number of retry attempts to complete the transfer. "10" by default.

isReversalAllowed: boolean value that determines if reversals are accepted for the transfer. It applies only to transfers made by Pix and to reversals with reason "customerRequest". Reversals for "fraud" or "bankError" are still accepted. "true" by default.

isPartialReversalAllowed: boolean value that determines if partial reversals are accepted for the transfer. It applies only to transfers made by Pix and to reversals with reason "customerRequest". Reversals for "fraud" or "bankError" are still accepted. "true" by default.

Note: The isPartialReversalAllowed rule should not be set to true if the isReversalAllowed rule is set to false.

**Request**

```python
import starkbank

transfers = starkbank.transfer.create([
    starkbank.Transfer(
        amount=1000000,
        tax_id="123.456.789-10",
        name="Daenerys Targaryen Stormborn",
        bank_code="20018183",
        branch_code="2201",
        account_number="76543-8",
        account_type="savings",
        rules=[
            starkbank.transfer.Rule(
                key="resendingLimit",
                value=5
            )
        ]
    )
])

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=savings,
    amount=1000000,
    bank_code=20018183,
    branch_code=2201,
    created=2020-02-06 16:22:24.664134,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=0,
    id=5412038532661248,
    name=Daenerys Targaryen Stormborn,
    rules=[
        Rule(
            key=resendingLimit,
            value=5
        )
    ],
    scheduled=2020-08-14 10:00:00,
    status=created,
    tags=[],
    tax_id=123.456.789-10,
    transaction_ids=[],
    updated=2020-02-06 16:22:24.664148
)
```

### Creating Transfers with description, externalId, tags parameters

Description: You can set a custom description to override the default description shown in your starkbank statement.

For example: "Payment for service #1234." Otherwise, the default description will be as follows: "Daenerys Targaryen Stormborn (123.456.789-10)." The name parameter concatenated with the taxId parameter.

ExternalId: Unique ID to prevent duplicate transfers. Repeated externalIds should cause failures by duplication.

By default, it blocks transfers to the same bank account with the same amount on the same day. Example: "my-internal-id"

Tags: Array of strings to tag the entity for future queries. All tags will be converted to lowercase. Example: ["daenerys", "invoice/1234"]

**Request**

```python
import starkbank

transfers = starkbank.transfer.create([
    starkbank.Transfer(
        amount=1000000,
        tax_id="123.456.789-10",
        name="Daenerys Targaryen Stormborn",
        bank_code="20018183",
        branch_code="2201",
        account_number="76543-8",
        external_id="my-external-id",
        tags=["daenerys", "invoice/1234"],
        description="Payment for service #1234"
    )
])

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=1000000,
    bank_code=20018183,
    branch_code=2201,
    created=2020-02-06 16:22:24.664134,
    description=Payment for service #1234,
    external_id=my-external-id,
    fee=0,
    id=5412038532661248,
    name=Daenerys Targaryen Stormborn,
    rules=[],
    scheduled=2020-08-14 10:00:00,
    status=created,
    tags=['daenerys', 'invoice/1234'],
    tax_id=123.456.789-10,
    transaction_ids=[],
    updated=2020-02-06 16:22:24.664148
)
```

### Creating Transfers with scheduled parameter

Scheduled: Schedule the transfer for a specific date.

Today is the default.

Ted Transfer's schedules for today will be accepted until 16:00 (BRT) and will be pushed to the next business day afterwards.

Pix Transfers are available 24/7 and can be scheduled for any date and time.

Example: "2020-08-14T15:23:26+00:00" or "2020-08-14"

**Request**

```python
import starkbank

transfers = starkbank.transfer.create([
    starkbank.Transfer(
        amount=1000000,
        tax_id="123.456.789-10",
        name="Daenerys Targaryen Stormborn",
        bank_code="20018183",
        branch_code="2201",
        account_number="76543-8",
        scheduled="2020-08-14"
    )
])

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=1000000,
    bank_code=20018183,
    branch_code=2201,
    created=2020-02-06 16:22:24.664134,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=0,
    id=5412038532661248,
    name=Daenerys Targaryen Stormborn,
    rules=[],
    scheduled=2020-08-14 10:00:00,
    status=created,
    tags=[],
    tax_id=123.456.789-10,
    transaction_ids=[],
    updated=2020-02-06 16:22:24.664148
)
```

### Listing Transfers

Get a list of Transfers using filters such as after, before, status and tags to narrow the results.

**Request**

```python
import starkbank

transfers = starkbank.transfer.query(
    after="2020-04-01",
    before="2020-04-30",
)

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=1000000,
    bank_code=665,
    branch_code=2201,
    created=2020-04-24 17:49:10.225810,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=200,
    id=5950134772826112,
    name=Daenerys Targaryen Stormborn,
    rules=[
        Rule(
            key=resendingLimit,
            value=5
        )
    ],
    status=processing,
    scheduled=2020-08-14 11:00:00,
    tags=['daenerys', 'invoice/1234'],
    tax_id=594.739.480-42,
    transaction_ids=['5991715760504832'],
    updated=2020-04-24 17:49:10.225810
)
```

### Getting a Transfer

Get a single Transfer by its id.

You can use it to check the current status of a Transfer.

**Request**

```python
import starkbank

transfer = starkbank.transfer.get("5950134772826112")

print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=1000000,
    bank_code=665,
    branch_code=2201,
    created=2020-04-24 17:49:10.225810,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=200,
    id=5950134772826112,
    name=Daenerys Targaryen Stormborn,
    rules=[
        Rule(
            key=resendingLimit,
            value=5
        )
    ],
    status=processing,
    scheduled=2020-08-14 11:00:00,
    tags=['daenerys', 'invoice/1234'],
    tax_id=594.739.480-42,
    transaction_ids=['5991715760504832'],
    updated=2020-04-24 17:49:10.225810
)
```

### Canceling Transfer

This method will allow the cancellation of a transfer.

It's important to note that it's only possible to cancel transfers before the start of processing.

**Request**

```python
import starkbank

transfer = starkbank.transfer.delete("6693962735681536")

print(transfer)
```

**Response**

```python
Transfer(
    account_number=76543-8,
    account_type=checking,
    amount=100000000,
    bank_code=665,
    branch_code=2201,
    created=2020-04-24 17:49:10.225810,
    description=Daenerys Targaryen Stormborn (594.739.480-42),
    external_id=my-external-id,
    fee=200,
    id=6693962735681536,
    name=Daenerys Targaryen Stormborn,
    rules=[
        Rule(
            key=resendingLimit,
            value=5
        )
    ],
    status=canceled,
    scheduled=2020-08-14 11:00:00,
    tags=['daenerys', 'invoice/1234'],
    tax_id=594.739.480-42,
    transaction_ids=['5991715760504832'],
    updated=2020-04-24 17:49:10.225810
)
```

### Receiving Transfer Webhook

After creation, you can use asynchronous Webhooks to monitor status changes of the entity. The Transfer will follow the following life cycle:

Every time we change a Transfer, we create a Log. Logs are pretty useful for understanding the life cycle of each Transfer. Whenever a new Log is created, we will fire a Webhook to your registered URL.

NOTE: Check the Webhook Get Started for more details on how to receive and process Webhook events.

NOTE: A transfer subscription is required to receive this event.

## Pix Key Overview

Pix Keys are saved in the DICT (Diretorio de Identificadores de Contas Transacionais), the centralized Pix service managed by Bacen (Brazilian Central Bank) that allows you to search for transactional accounts with convenient addressing keys.

The types of keys currently available are CPF, CNPJ, phone number, email and EVP (random UUID).

You can look up a Pix Key to retrieve the recipient's bank account data and use it to create a Pix Transfer without manually entering all the bank details.

Note: Try to avoid looking up DICT keys without sending transfers afterwards, since Bacen's system will block users making too many standalone requests in a short timespan. Invalid key searches also count towards this block.

### The Pix Key Object

**Parameters**

| Name | Type | Description |
| --- | --- | --- |
| `id` | STRING | Unique id for the Pix key (CPF, CNPJ, phone, email or EVP). |
| `accountNumber` | STRING | Account number. |
| `accountType` | STRING | Account type. Options: "checking", "savings", "salary", "payment". |
| `bankName` | STRING | Bank name. |
| `branchCode` | STRING | Account branch code. |
| `ispb` | STRING | Bank ISPB code. |
| `name` | STRING | Account owner full name. |
| `ownerType` | STRING | Account owner type. Options: "business", "personal". |
| `status` | STRING | Current key status. |
| `taxId` | STRING | Account owner CPF or CNPJ. |
| `type` | STRING | Key type. Options: "cpf", "cnpj", "phone", "email", "evp". |

### Getting a Pix Key

Get a single Pix Key by its id. You can retrieve a key's information using the SDKs or via the GET /dict-key/:id API route.

The returned data will include some encrypted parameters, but you shouldn't worry about it. Just pass the values as they come to the Transfer parameters.

Accepted key formats: email, phone number, CPF, CNPJ or EVP (random UUID).

**Request**

```python
import starkbank

dictkey = starkbank.dictkey.get("jon.snow@starkbank.com")

print(dictkey)
```

**Response**

```python
DictKey(
    account_number=*ZW5jcnlwdGVkLWFjY291bnQtbnVtYmVy,
    account_type=checking,
    branch_code=*ZW5jcnlwdGVkLWJyYW5jaC1jb2Rl,
    id=jon.snow@starkbank.com,
    ispb=67372284,
    name=Jon Snow,
    owner_type=naturalPerson,
    status=registered,
    tax_id=***.456.789-**,
    type=email
)
```

### Creating Transfer with Pix Key

To create a Transfer with a Pix Key, first look up the key to get the recipient's bank account data, then pass the returned parameters to POST /transfer.

The encrypted parameters (accountNumber, branchCode, taxId) can be used directly without decryption.

**Request**

```python
import starkbank

dict_key = starkbank.dictkey.get("jon.snow@starkbank.com")

transfers = starkbank.transfer.create([
    starkbank.Transfer(
        amount=1000000,
        tax_id=dict_key.tax_id,
        name=dict_key.name,
        bank_code=dict_key.ispb,
        branch_code=dict_key.branch_code,
        account_number=dict_key.account_number,
        account_type=dict_key.account_type
    )
])

for transfer in transfers:
    print(transfer)
```

**Response**

```python
Transfer(
    account_number=*ZW5jcnlwdGVkLWFjY291bnQtbnVtYmVy,
    account_type=checking,
    amount=1000000,
    bank_code=67372284,
    branch_code=*ZW5jcnlwdGVkLWJyYW5jaC1jb2Rl,
    created=2020-02-06 16:22:24.664134,
    description=Jon Snow (***.456.789-**),
    external_id=,
    fee=0,
    id=5412038532661248,
    name=Jon Snow,
    rules=[],
    scheduled=2020-08-14 10:00:00,
    status=created,
    tags=[],
    tax_id=***.456.789-**,
    transaction_ids=[],
    updated=2020-02-06 16:22:24.664148
)
```

---

## Other Languages

- [Python](https://docs.starkbank.com/get-started/transfer-python.md)
- [Node.js](https://docs.starkbank.com/get-started/transfer-node.md)
- [PHP](https://docs.starkbank.com/get-started/transfer-php.md)
- [Java](https://docs.starkbank.com/get-started/transfer-java.md)
- [Ruby](https://docs.starkbank.com/get-started/transfer-ruby.md)
- [Elixir](https://docs.starkbank.com/get-started/transfer-elixir.md)
- [.NET](https://docs.starkbank.com/get-started/transfer-dotnet.md)
- [Go](https://docs.starkbank.com/get-started/transfer-go.md)
- [Clojure](https://docs.starkbank.com/get-started/transfer-clojure.md)
- [cURL](https://docs.starkbank.com/get-started/transfer-curl.md)
