PayPal: Invoice, Send
PayPal: Invoice, Send
Sends an Invoice on the payment platform PayPal. Both Recipient (customer) and Invoicer will receive an email notification. The invoice status updates to SENT from DRAFT, and anyone who knows the Invoice URL will be able to pay.
Configs
  • A1: Select HTTP_Authz (BasicAuthn User:ClientID Passwd:SECRET) *
  • A2: Set Boolean for Notify Invoicer (true: DEFAULT, false: no)#{EL}
  • B1: Set PayPal Invoice Id *#{EL}
Script (click to open)
// GraalJS Script (engine type: 2)
/*
NOTES
- Invoicer can automate billing operations using the PayPal Invoicing via Invoices API.
    - https://www.paypal.com/merchantapps/appcenter/acceptpayments/invoicing
    - The invoices are controlled by a 24-character ID (e.g. "INV2-Z56S-5LLA-Q52L-CPZ5")
- This addon requires the CLIENT-ID and SECRET. (Get on the dashboard)
    - Developer Dashboard -> My apps & credentials -> REST API Apps (Live mode)
    - https://developer.paypal.com/developer/applications/
- Terminology in this addon is based on Invoices API v2 (2019-04).
    - Be careful when migrating from implementations prior to April 2019.
    - e.g. "merchant" to "invoicer"
    - e.g. "billing info" to "recipient"
- When PayPal emails the recipient, the invoice moves from draft to payable state.
    - To move from a draft to payable state, the SEND INVOICE action is required.
    - Invoice Status: DRAFT, SCHEDULED, SENT, PAID, MARKED_AS_PAID, CANCELLED, REFUNDED,,
    - https://developer.paypal.com/docs/api/invoicing/v2/#invoices_create
    - However, if "invoice_date" is set, automatically sent at 7:00 of Invoicer time zone
- The URL for viewing the invoice differs between the recipient and the invoicer.
    - recipient_view_url: https://www.paypal.com/invoice/p/#XXXX5MHSXXXXMXJH
    - invoicer_view_url: https://www.paypal.com/invoice/details/INV2-XXXX-5MHS-XXXX-MXJH

NOTE-ja
- 請求人は、請求書ツール(Invoicing)による請求業務を自動化できます(Invoices API経由)
    - https://www.paypal.com/jp/webapps/mpp/merchant/solutions/invoicing
    - 請求書は24文字のIDでコントロールされます(e.g. "INV2-Z56S-5LLA-Q52L-CPZ5")
- このアドオンの利用には CLIENT-ID と SECRET が必要です。(ダッシュボードで取得)
    - Developer Dashboard -> My apps & credentials -> REST API Apps (Live mode)
    - https://developer.paypal.com/developer/applications/
- このアドオンの表記は Invoices API v2 〔2019-04〕ベースの用語にて記載されています。
    - 2019-04 以前の実装から移行する場合は、特にご注意ください。
    - "merchant"(販売人) ではなく "invoicer"(請求人)
    - "billing info"(請求先) ではなく "recipient"(受取人)
- "請求書ドラフト" は原則、PayPalから受取人に対しメールされた際に決済可能な状態になります
    - すなわち請求書ドラフトを有効化するには、別途「送信」アクションが必要です。
    - Invoice Status: DRAFT, SCHEDULED, SENT, PAID, MARKED_AS_PAID, CANCELLED, REFUNDED,,
    - https://developer.paypal.com/docs/api/invoicing/v2/#invoices_create
    - ただし "請求日" がセットされた場合は、請求人タイムゾーンの 7:00 に自動送信されます
- 請求書表示用のURLは、受取人〔請求先〕用と請求人用で異なります。
    - recipient_view_url: https://www.paypal.com/invoice/p/#XXXX5MHSXXXXMXJH
    - invoicer_view_url: https://www.paypal.com/invoice/details/INV2-XXXX-5MHS-XXXX-MXJH
*/

/*
APPENDIX
- To request API in Sandbox mode (instead of Live mode)
    - Set CLIENT-ID and SECRET for Sandbox
    - Edit Access URLs to "api.sandbox.paypal.com" ('postUri1' and 'postUri2')
- PayPal API Reference "Send invoice" /v2/invoicing/invoices
    - https://developer.paypal.com/docs/invoicing/basic-integration/#3-send-invoice
    - https://developer.paypal.com/docs/api/invoicing/v2/#invoices_send

APPENDIX-ja
- テストのために(Live モードではなく)Sandbox モードで API 通信させたい場合
    - Sandbox 用の CLIENT-ID と SECRET をセット
    - スクリプト内のアクセスURLを "api.sandbox.paypal.com" に ('postUri1' と 'postUri2')
- PayPal API Reference "Send invoice" /v2/invoicing/invoices
    - https://developer.paypal.com/docs/invoicing/basic-integration/#3-send-invoice
    - https://developer.paypal.com/docs/api/invoicing/v2/#invoices_send
*/


//////// START "main()" /////////////////////////////////////////////////////////////////
main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==
const strAuthzSetting   = configs.get( "AuthzConfA1" ); // required (Authz by Basic_AuthN)
  engine.log( " AutomatedTask Config: Authz Setting: " + strAuthzSetting );
const strNoticesetting  = configs.get( "StrConfA2" ) + "";
  let boolNoticesetting = true;
  if( strNoticesetting === "false" ){
      boolNoticesetting = false;
  }
  engine.log( " AutomatedTask Config: Notification to Invoicer: " + boolNoticesetting );
const strInvoiceid      = configs.get( "StrConfB1" ) + ""; // required
  if( strInvoiceid     === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {B1 Invoice Id} not specified \n" );
  }


//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Retrieved via Expression Language in Config Retrieving)


//// == Calculating / 演算 ==
// prepare request1: Get an Access Token
// (PayPal OAuth 2.0 credentials / Client Credentials)
// https://developer.paypal.com/docs/api/overview#get-credentials
// https://developer.paypal.com/docs/api/get-an-access-token-curl/
let postUri1 = "https://api.paypal.com/v1/oauth2/token";
let request1 = httpClient.begin(); // HttpRequestWrapper
    request1 = request1.authSetting( strAuthzSetting );
    request1 = request1.formParam( "grant_type", "client_credentials" );
engine.log( " AutomatedTask ApiRequest1 Prepared" );

// try request1
const response1 = request1.post( postUri1 ); // HttpResponseWrapper
engine.log( " AutomatedTask ApiRequest1 Start: " + postUri1 );
const response1Code = response1.getStatusCode() + ""; // (primitive string)
const response1Body = response1.getResponseAsString() + "";
engine.log( " AutomatedTask ApiResponse1 Status: " + response1Code );
if( response1Code !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
                    response1Code + "\n" + response1Body + "\n" );
}

// parse response1
/*** engine.log( response1Body ); // debug
response sample
{
  "scope":"https://api.paypal.com/v1/payments/.※ https://uri.paypal.com/services/invoicing
           openid https://uri.paypal.com/payments/payouts ....",
  "access_token":"A21AAO9wpfXXXXXXXXXXL1P96HvZkRXXXXXXXXXXDlSVGSvUjlXXXXX...XXXXX",
  "token_type":"Bearer",
  "app_id":"APP-6BKXXX232XXX3090N",
  "expires_in":32400,
  "nonce":"2021-01-14T06:13:03Z1dgXXXCnnXXXgLKXXXgn0XXXcrJXXXoALXXXXBUXXXs"
}
***/
const response1Obj = JSON.parse( response1Body );
const strBearerToken = response1Obj.access_token;


// prepare request2: Send Invoice
let request2Obj = {};
    request2Obj.send_to_invoicer = boolNoticesetting;
let postUri2 = "https://api.paypal.com/v2/invoicing/invoices/" + strInvoiceid + "/send";
let request2 = httpClient.begin(); // HttpRequestWrapper
    request2 = request2.bearer( strBearerToken );
    request2 = request2.body( JSON.stringify( request2Obj ), "application/json" );
engine.log( " AutomatedTask ApiRequest2 Prepared" );

// try request2
const response2 = request2.post( postUri2 ); // HttpResponseWrapper
engine.log( " AutomatedTask ApiRequest2 Start: " + postUri2 );
const response2Code = response2.getStatusCode() + ""; // (primitive string)
const response2Body = response2.getResponseAsString() + "";
engine.log( " AutomatedTask ApiResponse2 Status: " + response2Code );
if( response2Code !== "200"){          // Reference wrong "202", Overview right "200"
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
                    response2Code + "\n" + response2Body + "\n" );
}
// https://developer.paypal.com/docs/api-basics/HTMLStatusCodes/

// parse response2
/*** engine.log( response2Body ); // debug
response sample
{
  "href":"https://www.paypal.com/invoice/p/#INV2-XXXX-DQHU-XXXX-UKG5",
  "rel":"payer-view",
  "method":"GET"
}
***/


//// == Data Updating / ワークフローデータへの代入 ==
// (No Output except Console Log)


} //////// END "main()" /////////////////////////////////////////////////////////////////

Download

2021-01-19 (C) Questetra, Inc. (MIT License)
https://support.questetra.com/addons/paypal-invoice-send/
The Addon-import feature is available with Professional edition.

Notes

Capture

Sends an Invoice on the payment platform PayPal. Both Recipient (customer) and Invoicer will receive an email notification. The invoice status updates to SENT from DRAFT, and anyone who knows the Invoice URL will be able to pay.

Appendix

See also

3 thoughts on “PayPal #Invoice: Send”

  1. Pingback: PayPal Invoicing Send – Questetra Support

  2. Pingback: PayPal: Invoice, Create Draft – Questetra Support

  3. Pingback: PayPal Billing Process – Questetra Support

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d