Create a Quarterly Tax Payment

The Quarterly Tax Payment represents the actual submission of money from the Payment Method to the IRS (or other government entity) on behalf of a User.

1: Determine the Tax Payment Amount

Before creating a Quarterly Tax Payment, you need to calculate the appropriate amount owed. To calculate the taxes owed for a specific user, read the Calculate Taxes Owed for a Specific User guide.

The following provides an example response from the GET /user/{userId}/taxes/{year} API endpoint:

{
  "data": {
    "1099Income": 180000,
    "effectiveTaxRate": 0.3006,
    "expenseDeduction": 865,
    "federalIncomeTax": 21408.98,
    "federalTaxOutstanding": 43281.28,
    "federalTaxTotal": 43281.28,
    "filingState": "ca",
    "filingStatus": "head_of_household",
    "irsPayments": 0,
    "quarterlyPayments": 0,
    "marginalTaxRate": 0.4545,
    "medicareTax": 4797.5,
    "mileage": 0,
    "mileageDeduction": 0,
    "otherIrsPayments": 0,
    "otherStatePayments": 0,
    "otherTaxWithholdings": 0,
    "qbiDeduction": 29969.77,
    "selfEmploymentTax": 21872.3,
    "smartTaxRate": 0.3776,
    "socialSecurityTax": 17074.8,
    "stateIncomeTax": 10826.78,
    "stateTaxTotal": 10826.78,
    "taxBalance": 54108.06,
    "taxWithholdings": 0,
    "taxWithholdingsPending": 0,
    "totalTax": 54108.06,
    "w2Income": 0,
    "year": "2020"
  },
  "request": {
    "requestId": "requestId_148a74444924c899f0fbd9df",
    "timestamp": 1612991495027
  }
}

For quarterly tax payments submitted to the IRS, the appropriate value to set as the amount for your Quarterly Tax Payment is the federalTaxOutstanding. This value represents the outstanding tax owed to the federal government after considering previous quarterly tax payment amounts submitted to the IRS. For the taxes object example above, the amount for the user’s Quarterly Tax Payment to the IRS would be 43281.28.

2: Submit a Tax Payment

📘

If your User's First and Last name exceeds 30 characters, there may be display issues on payment memo lines.

Federal Tax Payment

Below is an example of the creation of a Quarterly Tax Payment for the User. The funds are pulled from the Payment Method returned when you created your Payment Method as explained in the Prerequisites.

curl \
  --request POST \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments \
  --header 'Authorization: Bearer <<apiKey>>' \
  --header 'Content-Type: application/json' \
  --data '{
    "taxPayment": {
      "amount": 43281.28,
      "period": "Q3",
      "year": "2020",
      "entity": "IRS",
      "paymentMethodId": "<<testPaymentMethodId>>"
    }
  }'
const { default: Abound, Environment } = require("@withabound/node-sdk");

const abound = new Abound({
  appId: "<<sandbox_app_id>>",
  appSecret: "<<sandbox_app_secret>>",
  environment: Environment.SANDBOX,
  apiVersion: "v2",
});

(async () => {
  const response = await abound.taxPayments.create(
    "<<testUserId>>",
    {
      amount: 43281.28,
      period: "Q3",
      year: "2020",
      entity: "IRS",
      paymentMethodId:
        "<<testPaymentMethodId>>",
    }
  );

  console.log(response);
})();
import requests

url = "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments"

payload = {"taxPayment": {
        "amount": 43281.28,
        "period": "Q3",
        "year": "2020",
        "entity": "IRS",
        "paymentMethodId": "<<testPaymentMethodId>>"
    }}
headers = {
    "Accept": "application/json",
    "Content-Type": "application/json",
    "Authorization": "Bearer <<apiKey>>"
}

response = requests.request("POST", url, json=payload, headers=headers)

print(response.text)
// import com.squareup.okhttp.*;
// import com.google.gson.JsonObject;
// import com.google.gson.JsonArray;
// import com.withabound.AboundConfig;
// import com.withabound.models.*;
// import com.withabound.resources.base*;

AboundConfig aboundConfig = new AboundConfig(
  "<<sandbox_app_id>>",
  "<<sandbox_app_secret>>",
  AboundEnvironment.SANDBOX,
  AboundApiVersion.V2
);
Abound abound = new Abound(aboundConfig);
String userId = "<<testUserId>>";

TaxPaymentRequest taxPaymentRequest = TaxPaymentRequest.builder()
  .paymentMethodId(paymentMethodId)
  .year("2020")
  .period(TaxPeriod.Q3)
  .amount(43281.28)
  .entity(TaxPaymentEntity.IRS)
  .build();

AboundResponse<TaxPayment> response = abound.taxPayments().create(userId, taxPaymentRequest);

System.out.println(response.getData().getTaxPaymentId());
package main

import (
    "bytes"
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments"

    var requestBody = []byte(`{
        "taxPayment": {
            "amount": 43281.28,
            "period": "Q3",
            "year": "2020",
            "entity": "IRS",
            "paymentMethodId": "<<testPaymentMethodId>>"
        }
    }`)

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))

    req.Header.Add("Accept", "application/json")
    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Authorization", "Bearer <<apiKey>>")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
// using RestSharp;

var client = new RestClient("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments");
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "application/json");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer <<apiKey>>");
request.AddJsonBody(new {
  taxPayment = new {
    amount = 43281.28,
    period = "Q3",
    year = "2020",
    entity = "IRS",
    paymentMethodId = "<<testPaymentMethodId>>"
  }
});
IRestResponse response = client.Execute(request);
require 'uri'
require 'net/http'
require 'openssl'
require 'json'

url = URI("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments")
requestBody = {
  taxPayment: {
    amount: 43281.28,
    period: 'Q3',
    year: '2020',
    entity: 'IRS',
    paymentMethodId: '<<testPaymentMethodId>>'
  }
}

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Accept"] = 'application/json'
request["Content-Type"] = 'application/json'
request["Authorization"] = 'Bearer <<apiKey>>'
request.body = requestBody.to_json

response = http.request(request)
puts response.read_body

3: Monitor Payment Status

After your tax payment has been submitted, you can monitor the status of your payment via GET users/{userId}/taxPayments/{taxPaymentId} endpoint or webhook. Abound® will use webhooks to inform your backend when the tax payment has been updated. Read our Webhooks guide to learn more.

📘

First Time Submission

For each new user's first time submitting quarterly tax payment through Abound®, there will be a delay due to enrollment in the EFTPS process. This process is handled by the IRS.

The following provides a timeline that a Quarterly Tax Payment will go through if it processed successfully and without errors:

  1. Create a Quarterly Tax Payment, status = "created" (on or before the Abound® submission deadline)
  2. Quarterly Tax Payment is submitted to the IRS, status = "pending" (usually within 48 business hours of the Quarterly Tax Payment creation)

Once a payment is in pending it cannot be cancelled

  1. Quarterly Tax Payment is successfully received by the IRS, status = "done" (on or shortly after payment date)

There are circumstances where an error occurs, and we are unable to submit a payment for your User. To learn more about these error and how to resolve them, read our tax payments errors guide.

📅

Tax Payments are processed on a weekly basis

If it has been more than 7 business days, and the status of your payment has not changed, please contact us.

For both a successful and failed quarterly tax payments, it’s important that you be notified when there is an update to the status of your Quarterly Tax Payment. Abound® uses Webhooks to communicate with your servers when a relevant event occurs.

4: Retrieve Tax Payment Receipts

Once a user’s Federal Quarterly Tax Payment is successfully received by the IRS, the status will change to done, and the receipt for the Quarterly Tax Payment (called the 1040-ES) can be retrieved directly from the Quarterly Tax Payment object. The following demonstrates the request and response of GET /users/{userId}/taxPayments/{taxPaymentId} API call, showing the document object (representing the 1040-ES receipt) attached to the response:

curl \
  --request GET \
  --url https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments/<<testTaxPaymentId>> \
  --header 'Authorization: Bearer <<apiKey>>'
const { default: Abound, Environment } = require("@withabound/node-sdk");

const abound = new Abound({
  appId: "<<sandbox_app_id>>",
  appSecret: "<<sandbox_app_secret>>",
  environment: Environment.SANDBOX,
  apiVersion: "v2",
});

(async () => {
  const response = await abound.taxPayments.retrieve(
    "<<testUserId>>",
    "<<testTaxPaymentId>>"
  );

  console.log(response);
})();
import requests

url = "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments/<<testTaxPaymentId>>"

headers = {
    "Accept": "application/json",
    "Authorization": "Bearer <<apiKey>>"
}

response = requests.request("GET", url, headers=headers)

print(response.text)
// import com.squareup.okhttp.*;
// import com.google.gson.JsonObject;
// import com.google.gson.JsonArray;
// import com.withabound.AboundConfig;
// import com.withabound.models.*;
// import com.withabound.resources.base*;

AboundConfig aboundConfig = new AboundConfig(
  "<<sandbox_app_id>>",
  "<<sandbox_app_secret>>",
  AboundEnvironment.SANDBOX,
  AboundApiVersion.V2
);

String userId = "<<testUserId>>";
String taxPaymentId = "<<testTaxPaymentId>>";

AboundResponse<TaxPayment> response = abound.taxPayments().retrieve(userId, taxPaymentId);

System.out.println(response.getData().getStatus());
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments/<<testTaxPaymentId>>"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")
    req.Header.Add("Authorization", "Bearer <<apiKey>>")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
// using RestSharp;

var client = new RestClient("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments/<<testTaxPaymentId>>");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("Authorization", "Bearer <<apiKey>>");
IRestResponse response = client.Execute(request);
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://sandbox-api.withabound.com/v2/users/<<testUserId>>/taxPayments/<<testTaxPaymentId>>")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'
request["Authorization"] = 'Bearer <<apiKey>>'

response = http.request(request)
puts response.read_body
{
  "data": {
    "taxPaymentId": "<<testTaxPaymentId>>",
    "status": "done",
    "amount": 43281.28,
    "period": "Q3",
    "year": "2020",
    "entity": "IRS",
    "document": {
      "documentURL": "https://tax-documents-sandbox.s3.us-west-2.amazonaws.com/test62ae93bafa6310aa9952e8b3bf5796443111/Form_1040ES_Y2020-Q2.pdf?AWSAccessKeyId=AKIA6C6AUYYBZMXK74XQ&Expires=1629919919&Signature=FzjK06DpBKpzBqRf3vYNTK%2FcwAg%3D",
      "documentName": "2020 Q3 Federal Estimated Tax Payment",
      "type": "1040ES",
      "year": "2020",
    },
    "paymentMethodId": "<<testPaymentMethodId>>",
    "createdDate": "2020-09-18"
  }
}

Did this page help you?