# Billing

The `Billing` functions enable account billing management by adding or deleting
payment methods (credit cards and bank accounts), listing available payment methods, and
funding wallets.

All endpoints are only available in production environments.

  **Note**: Billing behavior depends on the carrier account type.

- **Wallet Carriers:** Charges are billed through the EasyPost Wallet, either at label purchase (bill-on-creation) or when the carrier scans the package (bill-on-scan).
- **BYOCA:** Charges are billed directly by the carrier. EasyPost does not process these payments.

For more details, review the individual Carrier Guides, and the EasyPost Wallet and Bring Your Own Carrier Account Plans Help Center article.

---

**Production Only**

## Create Credit Card

  **Important**: This endpoint is only applicable for `ReferralCustomers` or
  for managing Parent `User`accounts. If you feel this is applicable to your use case,
  please contact sales.

This section describes the steps to securely collect and store credit card details for `ReferralCustomers` using EasyPost’s integration with Stripe.
This process includes obtaining a `client_secret`, securely collecting card details with Stripe.js, and storing the payment method using EasyPost’s `/v2/credit_cards` endpoint.

### Obtain a Client Secret

### Example: POST /beta/setup_intents

#### cURL

```shell
curl -X POST "https://api.easypost.com/beta/setup_intents" \
  -u "$REFERRAL_USER_API_KEY:" \
  -H "Content-Type: application/json"
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func createStripeCreditCardSecret() {
	client := easypost.New("EASYPOST_API_KEY")

	response, _ := client.BetaCreateCreditCardClientSecret()

	fmt.Println(response)
}
```

#### Java

```java
package billing;

import com.easypost.exception.EasyPostException;
import com.easypost.service.EasyPostClient;

public class CreateStripeCreditCardSecret {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        ClientSecret response = client.betaReferralCustomer.createCreditCardClientSecret();

        System.out.println(response);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.StripeClientSecret response = await client.Beta.ReferralCustomer.CreateCreditCardClientSecret();

            Console.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const response = await client.BetaReferralCustomer.createCreditCardClientSecret();

  console.log(response);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$response = $client->betaReferralCustomer->createCreditCardClientSecret();

echo $response;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

response = client.beta_referral_customer.create_credit_card_client_secret()

print(response)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

response = client.beta_referral_customer.create_credit_card_client_secret

puts response
```

Call the `beta/setup_intents` endpoint to get a `client_secret` for securely collecting credit card details.

### Confirm the SetupIntents via Stripe.js

Use the `client_secret` obtained in the previous step to confirm the `SetupIntents` via Stripe.js. This step securely collects card details from the user.

- Create a Stripe Element using the client secret from the SetupIntents.
- Create a Payment Method using the Stripe Element.

### Store the Payment Method with EasyPost

### Example: POST /credit_cards

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/credit_cards \
  -u "$REFERRAL_USER_API_KEY": \
  -H "Content-Type: application/json" \
  -d '{
    "credit_card": {
      "payment_method_id": "pm_...",
      "priority": "primary"
    }
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func createEpCreditCard() {
	client := easypost.New("EASYPOST_API_KEY")

	creditCard, _ := client.AddReferralCustomerCreditCard("REFERRAL_USER_API_KEY", &easypost.CreditCardOptions{
		Number:   "0123456789101234",
		ExpMonth: "01",
		ExpYear:  "2025",
		Cvc:      "111",
	}, easypost.PrimaryPaymentMethodPriority)

	fmt.Println(creditCard)
}
```

#### Java

```java
package referral;

import com.easypost.exception.EasyPostException;
import com.easypost.service.EasyPostClient;

public class Create {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        PaymentMethodObject creditCard = client.referralCustomer.addCreditCardToUser("REFERRAL_USER_API_KEY",
                "0123456789101234", 01, 2025, "111", PaymentMethod.Priority.PRIMARY);

        System.out.println(referralUser);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.PaymentMethod paymentMethod = await client.ReferralCustomer.AddCreditCardToUser("REFERRAL_USER_API_KEY", "0123456789101234", "01", "2025", "111", PaymentMethod.Priority.Primary);

            Console.WriteLine(JsonConvert.SerializeObject(paymentMethod, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const creditCard = await client.Referral.addCreditCard(
    'REFERRAL_USER_API_KEY',
    '0123456789101234',
    '01',
    '2025',
    '111',
  );

  console.log(creditCard);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$creditCard = $client->referralCustomer->addCreditCard(
    'REFERRAL_USER_API_KEY',
    '0123456789101234',
    '01',
    '2025',
    '111'
);

echo $creditCard;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

credit_card = client.referral_customer.add_credit_card(
    referral_api_key="REFERRAL_USER_API_KEY",
    number="0123456789101234",
    expiration_month="01",
    expiration_year="2025",
    cvc="111",
)

print(credit_card)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

credit_card = client.referral_customer.add_credit_card(
  'REFERRAL_USER_API_KEY',
  '0123456789101234',
  '01',
  '2025',
  '111',
)

puts credit_card
```

Call the `/v2/credit_cards` endpoint with the resulting `payment_method_id` returned by Stripe. For additional details, refer to Stripe's SetupIntent Confirmation for Cards.

---

**Production Only**

## ACH Integration (For Bank Accounts)

This section explains the process for securely linking bank accounts for ACH payments using Stripe Financial Connections.

### Collect Bank Account Details

### Example: POST /beta/financial_connections_sessions

#### cURL

```shell
curl -X POST "https://api.easypost.com/beta/financial_connections_sessions" \
  -u "$REFERRAL_USER_API_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
    "return_url": "https://www.yourwebsite.com/redirect"
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func createStripeBankAccountSecret() {
	client := easypost.New("EASYPOST_API_KEY")

	response, _ := client.BetaCreateBankAccountClientSecret()

	fmt.Println(response)
}
```

#### Java

```java
package billing;

import com.easypost.exception.EasyPostException;
import com.easypost.service.EasyPostClient;

public class CreateStripeBankAccountSecret {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        ClientSecret response = client.betaReferralCustomer.createBankAccountClientSecret();

        System.out.println(response);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.StripeClientSecret response = await client.Beta.ReferralCustomer.CreateBankAccountClientSecret();

            Console.WriteLine(JsonConvert.SerializeObject(response, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const response = await client.BetaReferralCustomer.createBankAccountClientSecret();

  console.log(response);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$response = $client->betaReferralCustomer->createBankAccountClientSecret();

echo $response;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

response = client.beta_referral_customer.create_bank_account_client_secret()

print(response)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

response = client.beta_referral_customer.create_bank_account_client_secret

puts response
```

Call the `/beta/financial_connections_sessions` endpoint.

### Securely Link a Bank Account with Stripe.js

After receiving the `client_secret`, use Stripe.js to guide the customer through the Financial Connections process. This step allows the customer to securely log in and select a bank account. Refer to Stripe Financial Connections Process for more details.

### Create a Bank Account

### Example: POST /bank_accounts

#### cURL

```shell
curl -X POST "https://api.easypost.com/v2/bank_accounts" \
  -u "$REFERRAL_USER_API_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
    "financial_connections_id": "fca_...",
    "mandate_data": {
      "ip_address": "127.0.0.1",
      "user_agent": "Mozilla/5.0",
      "accepted_at": 1722510730,
    },
    "priority": "primary"
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func addStripeBankAccount() {
	client := easypost.New("EASYPOST_API_KEY")

	bankAccount, _ := client.AddReferralCustomerBankAccountFromStripe(
		"REFERRAL_USER_API_KEY",
		"fca_...",
		&easypost.MandateData{
			IpAddress:  "127.0.0.1",
			UserAgent:  "Mozilla/5.0",
			AcceptedAt: 1722510730,
		},
		easypost.PrimaryPaymentMethodPriority,
	)

	fmt.Println(bankAccount)
}
```

#### Java

```java
package billing;

import com.easypost.exception.EasyPostException;
import com.easypost.model.PaymentMethod;
import com.easypost.service.EasyPostClient;

public class CreateStripeCreditCardSecret {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        HashMap<String, Object> mandateData = new HashMap<String, Object>();
        mandateData.put("ip_address", "127.0.0.1");
        mandateData.put("user_agent", "Mozilla/5.0");
        mandateData.put("accepted_at", 1722510730);

        PaymentMethodObject paymentMethod = client.referralCustomer.addBankAccountFromStripe(
                "REFERRAL_USER_API_KEY",
                "fca_...",
                mandateData,
                PaymentMethod.Priority.PRIMARY
        );

        System.out.println(paymentMethod);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.PaymentMethod paymentMethod = await Client.ReferralCustomer.AddBankAccountFromStripe(
                "REFERRAL_USER_API_KEY",
                "fca_...",
                new Dictionary<string, object>
                {
                    { "ip_address", "127.0.0.1" },
                    { "user_agent", "Mozilla/5.0" },
                    { "accepted_at", 1722510730 }
                },
                EasyPost.Models.API.PaymentMethod.Priority.Primary
            );

            Console.WriteLine(JsonConvert.SerializeObject(paymentMethod, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const paymentMethod = await client.ReferralCustomer.addBankAccountFromStripe(
    'REFERRAL_USER_API_KEY',
    'fca_...',
    {
      ip_address: '127.0.0.1',
      user_agent: 'Mozilla/5.0',
      accepted_at: 172251073,
    },
    'primary',
  );

  console.log(paymentMethod);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$paymentMethod = $client->referralCustomer->addBankAccountFromStripe(
    'REFERRAL_USER_API_KEY',
    'fca_...',
    [
        'ip_address' => '127.0.0.1',
        'user_agent' => 'Mozilla/5.0',
        'accepted_at' => 172251073,
    ],
    'primary',
);

echo $paymentMethod;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

payment_method = client.referral_customer.add_bank_account_from_stripe(
    referral_api_key="REFERRAL_USER_API_KEY",
    financial_connections_id="fca_...",
    mandate_data={
        "ip_address": "127.0.0.1",
        "user_agent": "Mozilla/5.0",
        "accepted_at": 172251073,
    },
    priority="primary",
)

print(payment_method)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

payment_method = client.referral_customer.add_bank_account_from_stripe(
  'REFERRAL_USER_API_KEY',
  'fca_...',
  {
    ip_address: '127.0.0.1',
    user_agent: 'Mozilla/5.0',
    accepted_at: 172_251_073,
  },
  'primary',
)

puts payment_method
```

Once the bank account is linked, Stripe returns an `account_id` (e.g., `fca_…`). Use this `account_id` to call the `/v2/bank_accounts` endpoint with mandate data and the account owner’s full name.

---

**Production Only**

## Add Funds to your wallet (One-Time Charge)

### Example: Add Funds

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/credit_cards/card_.../charges \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "amount": "2000"
  }'
```

#### Go

```go
package example

import (
	"github.com/EasyPost/easypost-go/v5"
)

func fund() {
	client := easypost.New("EASYPOST_API_KEY")

	_ = client.FundWallet("2000", easypost.PrimaryPaymentMethodPriority)
}
```

#### Java

```java
package billing;

import com.easypost.exception.EasyPostException;
import com.easypost.model.PaymentMethod;
import com.easypost.service.EasyPostClient;

public class Fund {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        client.billing.fundWallet("2000", PaymentMethod.Priority.PRIMARY);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            await client.Billing.FundWallet("2000", PaymentMethod.Priority.Primary);
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  await client.Billing.fundWallet('2000', 'primary');
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$client->billing->fundWallet(2000, 'primary');
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

client.billing.fund_wallet(
    amount="2000",
    primary_or_secondary="primary",
)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

client.billing.fund_wallet('2000', 'primary')
```

Fund the EasyPost wallet by charging a primary or secondary payment method on file.
**The amount added must be greater than or equal to the current balance.**

Adding funds with one-time charges is **optional**, as EasyPost uses an automatic recharge system to maintain a wallet balance.

The API response for this endpoint is empty. EasyPost's client libraries return `true` if the API call is successful; otherwise, an error is thrown.

---

**Production Only**

## Retrieve Payment Methods

### Example: GET /payment_methods

#### cURL

```shell
curl -X GET https://api.easypost.com/v2/payment_methods \
  -u "EASYPOST_API_KEY":
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func list() {
	client := easypost.New("EASYPOST_API_KEY")

	paymentMethods, _ := client.RetrievePaymentMethods()

	fmt.Println(paymentMethods)
}
```

#### Java

```java
package billing;

import com.easypost.exception.EasyPostException;
import com.easypost.model.PaymentMethod;
import com.easypost.service.EasyPostClient;

public class All {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        PaymentMethod paymentMethods = client.billing.retrievePaymentMethods();

        System.out.println(paymentMethods);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Models.API.PaymentMethodsSummary paymentMethodsSummary = await client.Billing.RetrievePaymentMethodsSummary();

            Console.WriteLine(JsonConvert.SerializeObject(paymentMethodsSummary, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const paymentMethods = await client.Billing.all();

  console.log(paymentMethods);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$paymentMethods = $client->billing->retrievePaymentMethods();

echo $paymentMethods;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

payment_methods = client.billing.retrieve_payment_methods()

print(payment_methods)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

payment_methods = client.billing.retrieve_payment_methods

puts payment_methods
```

List payment methods associated with an account.

---

**Production Only**

## Delete a Payment Method

### Example: DELETE Payment

#### cURL

```shell
curl -X DELETE https://api.easypost.com/v2/credit_cards/card_... \
  -u "EASYPOST_API_KEY":
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func delete() {
	client := easypost.New("EASYPOST_API_KEY")

	err := client.DeletePaymentMethod(easypost.PrimaryPaymentMethodPriority)

	fmt.Println(err)
}
```

#### Java

```java
package billing;

import com.easypost.exception.EasyPostException;
import com.easypost.model.PaymentMethod;
import com.easypost.service.EasyPostClient;

public class Delete {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        client.billing.deletePaymentMethod(PaymentMethod.Priority.PRIMARY);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            await client.Billing.DeletePaymentMethod(PaymentMethod.Priority.Primary);
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  await client.Billing.deletePaymentMethod('primary');
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$client->billing->deletePaymentMethod('primary');
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

client.billing.delete_payment_method(primary_or_secondary="primary")
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

client.referral_customer.delete('primary')
```

Delete a payment method. The functions in our client libraries accept a `priority` parameter (`primary` or `secondary`), which abstracts the need to pass in payment method IDs or change endpoints used.

The API response for this endpoint is empty. The functions in our client libraries will return `true` if the API call succeeds or an error if it fails.