Skip to content

taxjar/taxjar-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TaxJar Sales Tax API for Java GitHub tag (latest SemVer)

TaxJar

Official Java client for the TaxJar API. For the API documentation, please visit https://developers.taxjar.com/api.


Getting Started
Package Dependencies
Authentication
Usage
Custom Options
Sandbox Environment
Tests
More Information
License
Support
Contributing


Getting Started

We recommend installing taxjar-java with Maven or Gradle. Before authenticating, get your API key from TaxJar.

Maven

Add the following dependency to your project's pom.xml file:

<dependency>
    <groupId>com.taxjar</groupId>
    <artifactId>taxjar-java</artifactId>
    <version>5.0.3</version>
</dependency>

Gradle

Add the following dependency to your project's build file:

compile "com.taxjar:taxjar-java:5.0.3"

Manual Installation

You can manually install the following JARs (including dependencies) here:

Package Dependencies

taxjar-java is built for Java 1.7+ and requires the following dependencies:

Authentication

To authenticate with our API, simply instantiate the client with your TaxJar API token:

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;

public class AuthenticationExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");
    }

}

You're now ready to use TaxJar! Check out our quickstart guide to get up and running quickly.

Usage

categories - List all tax categories
taxForOrder - Calculate sales tax for an order
listOrders - List order transactions
showOrder - Show order transaction
createOrder - Create order transaction
updateOrder - Update order transaction
deleteOrder - Delete order transaction
listRefunds - List refund transactions
showRefund - Show refund transaction
createRefund - Create refund transaction
updateRefund - Update refund transaction
deleteRefund - Delete refund transaction
listCustomers - List customers
showCustomer - Show customer
createCustomer - Create customer
updateCustomer - Update customer
deleteCustomer - Delete customer
ratesForLocation - List tax rates for a location (by zip/postal code)
nexusRegions - List nexus regions
validateAddress - Validate an address
validateVat - Validate a VAT number
summaryRates - Summarize tax rates for all regions


All methods in the Taxjar class support synchronous and asynchronous requests. For async examples, see the project's functional tests.

List all tax categories (API docs)

The TaxJar API provides product-level tax rules for a subset of product categories. These categories are to be used for products that are either exempt from sales tax in some jurisdictions or are taxed at reduced rates. You need not pass in a product tax code for sales tax calculations on product that is fully taxable. Simply leave that parameter out.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.categories.CategoryResponse;

public class CategoryExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            CategoryResponse res = client.categories();
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Calculate sales tax for an order (API docs)

Shows the sales tax that should be collected for a given order.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.taxes.TaxResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TaxExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("from_country", "US");
            params.put("from_zip", "92093");
            params.put("from_state", "CA");
            params.put("from_city", "La Jolla");
            params.put("from_street", "9500 Gilman Drive");
            params.put("to_country", "US");
            params.put("to_zip", "90002");
            params.put("to_state", "CA");
            params.put("to_city", "Los Angeles");
            params.put("to_street", "1335 E 103rd St");
            params.put("amount", 15);
            params.put("shipping", 1.5);

            List<Map> nexusAddresses = new ArrayList();
            Map<String, Object> nexusAddress = new HashMap<>();
            nexusAddress.put("country", "US");
            nexusAddress.put("zip", "92093");
            nexusAddress.put("state", "CA");
            nexusAddress.put("city", "La Jolla");
            nexusAddress.put("street", "9500 Gilman Drive");
            nexusAddresses.add(nexusAddress);

            List<Map> lineItems = new ArrayList();
            Map<String, Object> lineItem = new HashMap<>();
            lineItem.put("id", 1);
            lineItem.put("quantity", 1);
            lineItem.put("product_tax_code", "20010");
            lineItem.put("unit_price", 15);
            lineItem.put("discount", 0);
            lineItems.add(lineItem);

            params.put("nexus_addresses", nexusAddresses);
            params.put("line_items", lineItems);

            TaxResponse res = client.taxForOrder(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

List order transactions (API docs)

Lists existing order transactions created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.OrdersResponse;
import java.util.HashMap;
import java.util.Map;

public class ListOrdersExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, String> params = new HashMap<>();
            params.put("from_transaction_date", "2015/05/01");
            params.put("to_transaction_date", "2015/05/31");
            OrdersResponse res = client.listOrders(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Show order transaction (API docs)

Shows an existing order transaction created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.OrderResponse;

public class ShowOrderExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            OrderResponse res = client.showOrder("123");
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Create order transaction (API docs)

Creates a new order transaction.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.OrderResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CreateOrderExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("transaction_id", "123");
            params.put("transaction_date", "2015/05/04");
            params.put("from_country", "US");
            params.put("from_zip", "92093");
            params.put("from_state", "CA");
            params.put("from_city", "La Jolla");
            params.put("from_street", "9500 Gilman Drive");
            params.put("to_country", "US");
            params.put("to_zip", "90002");
            params.put("to_state", "CA");
            params.put("to_city", "Los Angeles");
            params.put("to_street", "123 Palm Grove Ln");
            params.put("amount", 16.5);
            params.put("shipping", 1.5);
            params.put("sales_tax", 0.95);

            List<Map> lineItems = new ArrayList();
            Map<String, Object> lineItem = new HashMap<>();
            lineItem.put("id", "1");
            lineItem.put("quantity", 1);
            lineItem.put("product_identifier", "12-34243-0");
            lineItem.put("description", "Heavy Widget");
            lineItem.put("unit_price", 15);
            lineItem.put("discount", 0);
            lineItem.put("sales_tax", 0.95);
            lineItems.add(lineItem);

            params.put("line_items", lineItems);

            OrderResponse res = client.createOrder(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Update order transaction (API docs)

Updates an existing order transaction created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.OrderResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UpdateOrderExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("transaction_id", "123");
            params.put("transaction_date", "2015/05/04");
            params.put("from_country", "US");
            params.put("from_zip", "92093");
            params.put("from_state", "CA");
            params.put("from_city", "La Jolla");
            params.put("from_street", "9500 Gilman Drive");
            params.put("to_country", "US");
            params.put("to_zip", "90002");
            params.put("to_state", "CA");
            params.put("to_city", "Los Angeles");
            params.put("to_street", "123 Palm Grove Ln");
            params.put("amount", 17);
            params.put("shipping", 2);
            params.put("sales_tax", 0.95);

            List<Map> lineItems = new ArrayList();
            Map<String, Object> lineItem = new HashMap<>();
            lineItem.put("id", "1");
            lineItem.put("quantity", 1);
            lineItem.put("product_identifier", "12-34243-0");
            lineItem.put("description", "Heavy Widget");
            lineItem.put("unit_price", 15);
            lineItem.put("discount", 0);
            lineItem.put("sales_tax", 0.95);
            lineItems.add(lineItem);

            params.put("line_items", lineItems);

            OrderResponse res = client.updateOrder("123", params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Delete order transaction (API docs)

Deletes an existing order transaction created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.OrderResponse;

public class DeleteOrderExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            OrderResponse res = client.deleteOrder("123");
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

List refund transactions (API docs)

Lists existing refund transactions created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.RefundsResponse;
import java.util.HashMap;
import java.util.Map;

public class ListRefundsExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, String> params = new HashMap<>();
            params.put("from_transaction_date", "2015/05/01");
            params.put("to_transaction_date", "2015/05/31");
            RefundsResponse res = client.listRefunds(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Show refund transaction (API docs)

Shows an existing refund transaction created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.RefundResponse;

public class ShowRefundExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            RefundResponse res = client.showRefund("123-refund");
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Create refund transaction (API docs)

Creates a new refund transaction.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.RefundResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CreateRefundExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("transaction_id", "123-refund");
            params.put("transaction_reference_id", "123");
            params.put("transaction_date", "2015/05/04");
            params.put("from_country", "US");
            params.put("from_zip", "92093");
            params.put("from_state", "CA");
            params.put("from_city", "La Jolla");
            params.put("from_street", "9500 Gilman Drive");
            params.put("to_country", "US");
            params.put("to_zip", "90002");
            params.put("to_state", "CA");
            params.put("to_city", "Los Angeles");
            params.put("to_street", "123 Palm Grove Ln");
            params.put("amount", -16.5);
            params.put("shipping", -1.5);
            params.put("sales_tax", -0.95);

            List<Map> lineItems = new ArrayList();
            Map<String, Object> lineItem = new HashMap<>();
            lineItem.put("id", "1");
            lineItem.put("quantity", 1);
            lineItem.put("product_identifier", "12-34243-0");
            lineItem.put("description", "Heavy Widget");
            lineItem.put("unit_price", -15);
            lineItem.put("discount", -0);
            lineItem.put("sales_tax", -0.95);
            lineItems.add(lineItem);

            params.put("line_items", lineItems);

            RefundResponse res = client.createRefund(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Update refund transaction (API docs)

Updates an existing refund transaction created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.RefundResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UpdateRefundExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("transaction_id", "123-refund");
            params.put("transaction_reference_id", "123");
            params.put("transaction_date", "2015/05/04");
            params.put("from_country", "US");
            params.put("from_zip", "92093");
            params.put("from_state", "CA");
            params.put("from_city", "La Jolla");
            params.put("from_street", "9500 Gilman Drive");
            params.put("to_country", "US");
            params.put("to_zip", "90002");
            params.put("to_state", "CA");
            params.put("to_city", "Los Angeles");
            params.put("to_street", "123 Palm Grove Ln");
            params.put("amount", -17);
            params.put("shipping", -2);
            params.put("sales_tax", -0.95);

            List<Map> lineItems = new ArrayList();
            Map<String, Object> lineItem = new HashMap<>();
            lineItem.put("id", "1");
            lineItem.put("quantity", 1);
            lineItem.put("product_identifier", "12-34243-0");
            lineItem.put("description", "Heavy Widget");
            lineItem.put("unit_price", -15);
            lineItem.put("discount", -0);
            lineItem.put("sales_tax", -0.95);
            lineItems.add(lineItem);

            params.put("line_items", lineItems);

            RefundResponse res = client.updateRefund("321", params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Delete refund transaction (API docs)

Deletes an existing refund transaction created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.transactions.RefundResponse;

public class DeleteOrderExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            OrderResponse res = client.deleteRefund("123-refund");
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

List customers (API docs)

Lists existing customers created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.customers.CustomersResponse;
import java.util.HashMap;
import java.util.Map;

public class ListCustomersExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            CustomersResponse res = client.listCustomers();
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Show customer (API docs)

Shows an existing customer created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.customers.CustomerResponse;

public class ShowCustomerExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            CustomerResponse res = client.showCustomer("123");
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Create customer (API docs)

Creates a new customer.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.customers.CustomerResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CreateCustomerExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("customer_id", "123");
            params.put("exemption_type", "wholesale");
            params.put("name", "Dunder Mifflin Paper Company");
            params.put("country", "US");
            params.put("state", "PA");
            params.put("zip", "18504");
            params.put("city", "Scranton");
            params.put("street", "1725 Slough Avenue");

            List<Map> exemptRegions = new ArrayList();

            Map<String, String> exemptRegion = new HashMap<>();
            exemptRegion.put("country", "US");
            exemptRegion.put("state", "FL");

            Map<String, String> exemptRegion2 = new HashMap<>();
            exemptRegion.put("country", "US");
            exemptRegion.put("state", "PA");

            exemptRegions.add(exemptRegion);
            exemptRegions.add(exemptRegion2);

            params.put("exempt_regions", exemptRegions);

            CustomerResponse res = client.createCustomer(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Update customer (API docs)

Updates an existing customer created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.customers.CustomerResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UpdateCustomerExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("customer_id", "123");
            params.put("exemption_type", "wholesale");
            params.put("name", "Sterling Cooper");
            params.put("country", "US");
            params.put("state", "NY");
            params.put("zip", "10010");
            params.put("city", "New York");
            params.put("street", "405 Madison Ave");

            List<Map> exemptRegions = new ArrayList();

            Map<String, String> exemptRegion = new HashMap<>();
            exemptRegion.put("country", "US");
            exemptRegion.put("state", "NY");

            exemptRegions.add(exemptRegion);

            params.put("exempt_regions", exemptRegions);

            CustomerResponse res = client.updateCustomer("123", params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Delete customer (API docs)

Deletes an existing customer created through the API.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.customers.CustomerResponse;

public class DeleteCustomerExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            CustomerResponse res = client.deleteCustomer("123");
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

List tax rates for a location (by zip/postal code) (API docs)

Shows the sales tax rates for a given location.

Please note this method only returns the full combined rate for a given location. It does not support nexus determination, sourcing based on a ship from and ship to address, shipping taxability, product exemptions, customer exemptions, or sales tax holidays. We recommend using taxForOrder to accurately calculate sales tax for an order).

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.rates.RateResponse;
import java.util.HashMap;
import java.util.Map;

public class RatesExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, String> params = new HashMap<>();
            params.put("country", "US");
            params.put("city", "Watts");
            params.put("street", "123 Test St");
            RateResponse res = client.ratesForLocation("90002", params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

List nexus regions (API docs)

Lists existing nexus locations for a TaxJar account.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.nexus.RegionResponse;

public class NexusRegionsExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            RegionResponse res = client.nexusRegions();
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Validate an address (API docs)

Validates a customer address and returns back a collection of address matches. Address validation requires a TaxJar Plus subscription.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.validations.AddressResponse;
import java.util.HashMap;
import java.util.Map;

public class ValidateAddressExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("country", "US");
            params.put("state", "AZ");
            params.put("zip", "85297");
            params.put("city", "Gilbert");
            params.put("street", "3301 South Greenfield Rd");

            ValidateAddressResponse res = client.validateAddress(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Validate a VAT number (API docs)

Validates an existing VAT identification number against VIES.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.validations.ValidationResponse;
import java.util.HashMap;
import java.util.Map;

public class ValidateExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            Map<String, String> params = new HashMap<>();
            params.put("vat", "FR40303265045");

            ValidationResponse res = client.validateVat(params);
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Summarize tax rates for all regions (API docs)

Retrieve minimum and average sales tax rates by region as a backup.

This method is useful for periodically pulling down rates to use if the TaxJar API is unavailable. However, it does not support nexus determination, sourcing based on a ship from and ship to address, shipping taxability, product exemptions, customer exemptions, or sales tax holidays. We recommend using taxForOrder to accurately calculate sales tax for an order.

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import com.taxjar.model.summarized_rates.SummaryRateResponse;

public class SummarizedRatesExample {

    public static void main(String[] args) {
        Taxjar client = new Taxjar("YOUR API TOKEN");

        try {
            SummaryRateResponse res = client.summaryRates();
        } catch (TaxjarException e) {
            e.printStackTrace();
        }
    }

}

Custom Options

You can pass additional options using setApiConfig or when instantiating the client for the following:

API Version / Headers

Pass an API version with x-api-version or pass additional request headers:

import com.taxjar.Taxjar;
import java.util.HashMap;
import java.util.Map;

public class CustomHeaderExample {

    public static void main(String[] args) {
        // Custom header when instantiating the client
        Map<String, Object> params = new HashMap<>();
        Map<String, String> headers = new HashMap<>();
        
        headers.put("x-api-version", "2020-08-07");
        params.put("headers", headers);

        Taxjar client = new Taxjar("YOUR API TOKEN", params);

        // Custom header via `setApiConfig`
        client.setApiConfig("headers", headers);
    }

}

Timeouts

The default timeout is 30 seconds (specified in milliseconds).

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import java.util.HashMap;
import java.util.Map;

public class CustomTimeoutExample {

    public static void main(String[] args) {
        // Custom timeout when instantiating the client
        Map<String, Object> params = new HashMap<>();
        params.put("timeout", 30 * 1000);

        Taxjar client = new Taxjar("YOUR API TOKEN", params);

        // Custom timeout via `setApiConfig`
        client.setApiConfig("timeout", 30 * 1000);
    }

}

Sandbox Environment

You can easily configure the client to use the TaxJar Sandbox:

import com.taxjar.Taxjar;
import com.taxjar.exception.TaxjarException;
import java.util.HashMap;
import java.util.Map;

public class SandboxExample {

    public static void main(String[] args) {
        Map<String, Object> params = new HashMap<>();
        params.put("apiUrl", Taxjar.SANDBOX_API_URL);

        Taxjar client = new Taxjar("YOUR SANDBOX API TOKEN", params);
    }

}

Tests

We use JUnit v3.8.1 with a custom interceptor for Retrofit to directly test client methods.

More Information

More information can be found at TaxJar Developers.

License

taxjar-java is released under the MIT License.

Support

Bug reports and feature requests should be filed on the GitHub issue tracking page.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new pull request