Delphi ActiveX Requires Chilkat v11.0.0+
Delphi ActiveX
PayPal: Get a payable invoice link for your own email
See more PayPal Examples
Use a draft dated today or earlier. Make it payable with customer email suppressed, then retrieve the recipient view URL for the merchant's email. Future-dated invoices are scheduled for delivery and should use a different workflow.
Chilkat Delphi ActiveX Downloads
var
success: Integer;
http: TChilkatHttp;
resp: TChilkatHttpResponse;
errorInfo: TChilkatJsonObject;
result: TChilkatJsonObject;
parsedResult: Integer;
now: TCkDateTime;
stamp: TChilkatStringBuilder;
issue: TCkDateTime;
validDate: Integer;
body: TChilkatJsonObject;
sendError: TChilkatJsonObject;
invoiceError: TChilkatJsonObject;
invoice: TChilkatJsonObject;
parsedInvoice: Integer;
begin
success := 0;
// See Unlock Chilkat before making requests.
// For the merchant's internal backoffice application. Load the sandbox token
// from the merchant's credential store. Keep it out of publicly distributed apps.
// See Get a PayPal access token.
http := TChilkatHttp.Create(Self);
http.AuthToken := 'SANDBOX_ACCESS_TOKEN';
resp := TChilkatHttpResponse.Create(Self);
http.SetUrlVar('id','INVOICE_ID');
success := http.HttpNoBody('GET','https://api-m.sandbox.paypal.com/v2/invoicing/invoices/{$id}',resp.ControlInterface);
if (success <> 1) then
begin
Memo1.Lines.Add('No HTTP response: ' + http.LastErrorText);
Exit;
end;
if ((resp.StatusCode < 200) or (resp.StatusCode >= 300)) then
begin
errorInfo := TChilkatJsonObject.Create(Self);
errorInfo.Load(resp.BodyStr);
Memo1.Lines.Add('HTTP ' + IntToStr(resp.StatusCode) + ' ' + errorInfo.StringOf('name') + ' ' + errorInfo.StringOf('details[0].issue'));
Memo1.Lines.Add('PayPal debug ID: ' + errorInfo.StringOf('debug_id'));
Exit;
end;
result := TChilkatJsonObject.Create(Self);
parsedResult := result.Load(resp.BodyStr);
if (parsedResult <> 1) then
begin
Memo1.Lines.Add('Expected a JSON response; HTTP ' + IntToStr(resp.StatusCode));
Exit;
end;
if (result.StringOfEquals('status','DRAFT',1) <> 1) then
begin
Memo1.Lines.Add('Select an unsent draft.');
Exit;
end;
// Compare the ISO calendar dates at UTC midnight before asking PayPal to send.
now := TCkDateTime.Create(Self);
now.SetFromCurrentSystemTime();
stamp := TChilkatStringBuilder.Create(Self);
stamp.Append(result.StringOf('detail.invoice_date'));
stamp.Append('T00:00:00Z');
issue := TCkDateTime.Create(Self);
validDate := issue.SetFromTimestamp(stamp.GetAsString());
if ((validDate <> 1) or (now.DiffSeconds(issue.ControlInterface) < 0)) then
begin
Memo1.Lines.Add('Select a draft with an issue date of today or earlier.');
Exit;
end;
body := TChilkatJsonObject.Create(Self);
body.UpdateBool('send_to_recipient',0);
body.UpdateBool('send_to_invoicer',0);
success := http.HttpJson('POST','https://api-m.sandbox.paypal.com/v2/invoicing/invoices/{$id}/send',body.ControlInterface,'application/json',resp.ControlInterface);
if (success <> 1) then
begin
Memo1.Lines.Add('No HTTP response: ' + http.LastErrorText);
Exit;
end;
if ((resp.StatusCode < 200) or (resp.StatusCode >= 300)) then
begin
sendError := TChilkatJsonObject.Create(Self);
sendError.Load(resp.BodyStr);
Memo1.Lines.Add('HTTP ' + IntToStr(resp.StatusCode) + ' ' + sendError.StringOf('name') + ' ' + sendError.StringOf('details[0].issue'));
Memo1.Lines.Add('PayPal debug ID: ' + sendError.StringOf('debug_id'));
Exit;
end;
// Read back the invoice: acceptance of the send alone does not guarantee it is payable.
success := http.HttpNoBody('GET','https://api-m.sandbox.paypal.com/v2/invoicing/invoices/{$id}',resp.ControlInterface);
if (success <> 1) then
begin
Memo1.Lines.Add('No HTTP response: ' + http.LastErrorText);
Exit;
end;
if ((resp.StatusCode < 200) or (resp.StatusCode >= 300)) then
begin
invoiceError := TChilkatJsonObject.Create(Self);
invoiceError.Load(resp.BodyStr);
Memo1.Lines.Add('HTTP ' + IntToStr(resp.StatusCode) + ' ' + invoiceError.StringOf('name') + ' ' + invoiceError.StringOf('details[0].issue'));
Memo1.Lines.Add('PayPal debug ID: ' + invoiceError.StringOf('debug_id'));
Exit;
end;
invoice := TChilkatJsonObject.Create(Self);
parsedInvoice := invoice.Load(resp.BodyStr);
if (parsedInvoice <> 1) then
begin
Memo1.Lines.Add('Expected a JSON response; HTTP ' + IntToStr(resp.StatusCode));
Exit;
end;
if (((invoice.StringOfEquals('status','SENT',1) = 1) or (invoice.StringOfEquals('status','UNPAID',1) = 1) or (invoice.StringOfEquals('status','SHARED',1) = 1)) and (invoice.HasMember('detail.metadata.recipient_view_url') = 1)) then
begin
Memo1.Lines.Add('Customer payment page: ' + invoice.StringOf('detail.metadata.recipient_view_url'));
Exit;
end;
Memo1.Lines.Add('Invoice is ' + invoice.StringOf('status') + '. Retrieve it again when payable.');