I create recurring payment profile with regular payments. But I want to create profile with one-off payment which will occurs immediately after profile created. How I can do it?
I create profile in follow way:
var currency = CurrencyCodeType.USD;
var startBillingDate = DateTime.Now;
var rpProfileDetails =
new RecurringPaymentsProfileDetailsType(startBillingDate.ToString("yyyy-MM-ddThh:mm:ss"))
{
SubscriberName = "John Smith"
};
var scheduleDetails = new ScheduleDetailsType
{
Description = "Application Licenses",
AutoBillOutstandingAmount = AutoBillType.ADDTONEXTBILLING,
PaymentPeriod = new BillingPeriodDetailsType(BillingPeriodType.MONTH, pLicence.BillingPeriodAmount,
new BasicAmountType(currency,
"10.00"))
{
TotalBillingCycles = 12,
TaxAmount = new BasicAmountType(currency, "2.00")
}
};
You need to include the INITAMT parameter in your CreateRecurringPaymentsProfile request. You can find more details about it in PayPal's CreateRecurringPaymentsProfile API reference.
Related
I created an app on PayPal with sandbox account. Then i picked up its API Client id and Secret.
I created a new console application and added paypal nuget package version 1.9.1.
internal class Program { static void Main(string[] args) { // Get a reference to the config var config = ConfigManager.Instance.GetProperties();
// Use OAuthTokenCredential to request an access token from PayPal
var accessToken = new OAuthTokenCredential(config["clientId"], config["clientSecret"]);
var apiContext = new APIContext(accessToken.GetAccessToken());
try
{
var payment = new Payment()
{
intent = "authorize",
// A resource representing a Payer that funds a payment. Use the List of `FundingInstrument` and the Payment Method as 'credit_card'
payer = new Payer()
{
// The Payment creation API requires a list of
// FundingInstrument; add the created `FundingInstrument`
// to a List
funding_instruments = new List<FundingInstrument>()
{
// A resource representing a Payeer's funding instrument.
// Use a Payer ID (A unique identifier of the payer generated
// and provided by the facilitator. This is required when
// creating or using a tokenized funding instrument)
// and the `CreditCardDetails`
new FundingInstrument()
{
// A resource representing a credit card that can be used to fund a payment.
credit_card = new CreditCard()
{
billing_address = new Address()
{
city = "Johnstown",
country_code = "US",
line1 = "52 N Main ST",
postal_code = "43210",
state = "OH"
},
cvv2 = "874",
expire_month = 11,
expire_year = 2023,
first_name = "Joe",
last_name = "Shopper",
number = "5105105105105100",
type = "visa"
}
}
},
payment_method = "credit_card"
},
// The Payment creation API requires a list of transactions; add the created `Transaction` to a List
transactions = new List<Transaction>()
{
// A transaction defines the contract of a payment - what is the payment for and who is fulfilling it. Transaction is created with a `Payee` and `Amount` types
new Transaction()
{
// Let's you specify a payment amount.
amount = new Amount()
{
currency = "USD",
// Total must be equal to sum of shipping, tax and subtotal.
total = "107.47",
details = new Details()
{
shipping = "0.03",
subtotal = "107.41",
tax = "0.03"
}
},
description = "This is the payment transaction description."
}
},
payee = new Payee { email = "rassmasood#hotmail.com" }
};
var createdPayment = payment.Create(apiContext);
}
catch (Exception ex)
{
throw;
}
}
}
Using the code above i get the error mentioned below.
{"name":"VALIDATION_ERROR","message":"Invalid request - see details","debug_id":"f3c178cb2a17b","details":[{"field":"/payee","location":"body","issue":"MALFORMED_REQUEST_JSON"}],"links":[]}
is there anything i am doing wrong ?
i tried adding more information to Payee for example its account merchand_id and stuff but didnt worked.
i am expecting the exception to be resolved.
The package you are using is 5 years old and deprecated.
Use the current PayPalCheckoutSDK 1.0.4
i installed the .net sdk of paypal and created an app in sandbox environment
next i picked up the clientId and secret and used the following sample code to make a payment.
static void Main(string[] args)
{
// Get a reference to the config
var config = ConfigManager.Instance.GetProperties();
// Use OAuthTokenCredential to request an access token from PayPal
var accessToken = new OAuthTokenCredential(config["clientId"], config["clientSecret"]);
var apiContext = new APIContext(accessToken.GetAccessToken());
var payment = Payment.Create(apiContext, new Payment
{
intent = "sale",
payer = new Payer
{
payment_method = "paypal"
},
transactions = new List<Transaction>
{
new Transaction
{
description = "Test",
invoice_number = "009",
amount = new Amount
{
currency = "EUR",
total = "41.00",
details = new Details
{
tax = "0",
shipping = "0",
subtotal = "40",
handling_fee = "1"
}
},
item_list = new ItemList
{
items = new List<Item>
{
new Item
{
name = "Room 12",
currency = "EUR",
price = "10",
quantity = "4",
}
}
}
}
},
redirect_urls = new RedirectUrls
{
return_url = "https://google.de/",
cancel_url = "https://google.de/"
}
});
}
in the transaction i have to pass Tax information.
Is there was that i let paypal calculate the tax and i just pass amount information along with address and some other information if required ?
No, you must calculate the tax yourself.
By default the user will be able to select their shipping address at PayPal, which is recommended as this saves them from having to type it manually. Given that their address can change during the PayPal checkout, you may wish to calculate a new tax amount and/or shipping amount based on the selected address. You can do this using the JS SDK's onShippingChange callback.
Firstly, though, it appears you may be using a deprecated SDK and deprecated v1/payments API, and also a redirect away from your site to PayPal, all of which is old. Don't do any of this.
Instead: follow the PayPal Checkout integration guide and make 2 routes on your server, one for 'Create Order' and one for 'Capture Order' (see the optional step 5 in 'Add and modify the code'). Both of these routes should return only JSON data (no HTML or text). There is a Checkout-Java-SDK you can use, or integrate with your own direct HTTPS API calls (obtain an access_token first, it can be cached but expires in 9 hours).
Inside the 2nd capture route on your server, when the capture API call is successful you should store its resulting payment details in your database (particularly purchase_units[0].payments.captures[0].id, which is the PayPal transaction ID) and perform any necessary business logic (such as sending confirmation emails or reserving product) immediately before forwarding your return JSON to the frontend caller.
Pair those 2 routes with the frontend approval flow: https://developer.paypal.com/demo/checkout/#/pattern/server
I am having a difficult time finding halfway descent documentation or examples on how to send money to another Paypal account.
I have installed the Nuget package PaypalSDK version 1.0.4. I have read the documentation at https://developer.paypal.com/home. I have browsed and tried to implement the sample code at https://github.com/paypal/Checkout-NET-SDK.
The problem I am having is that I am having is that I am not seeing notifications of payments sent or received in my sandbox account. I can successfully execute a checkout with the Javascript button in my shopping cart view. But eventually I want to add the capability to send money from my Paypal business account to another Paypal business account, without the other Paypal Business Account owner having to be logged in to my website.
Does the money recipient have to authorize the money I send, or should it just get deposited into their account once I send it?
Here is my code:
namespace MyShoppingCart.Helpers.Paypal
{
public class CaptureOrderSample
{
static string PayPalClientID = Startup.StaticConfig.GetValue<string>("Paypal:ClientID");
static string PayPalClientSecret = Startup.StaticConfig.GetValue<string>("Paypal:ClientSecret");
public static HttpClient client()
{
// Creating a sandbox environment
PayPalEnvironment environment = new SandboxEnvironment(PayPalClientID, PayPalClientSecret);
// Creating a client for the environment
PayPalHttpClient client = new PayPalHttpClient(environment);
return client;
}
public async static Task<HttpResponse> createOrder(string Email)
{
HttpResponse response;
// Construct a request object and set desired parameters
// Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
var order = new OrderRequest()
{
CheckoutPaymentIntent = "CAPTURE",
PurchaseUnits = new List<PurchaseUnitRequest>()
{
new PurchaseUnitRequest()
{
AmountWithBreakdown = new AmountWithBreakdown()
{
CurrencyCode = "USD",
Value = "100.00"
},
Payee = new Payee
{
Email = Email // "payee#email.com"
}
}
}
//,
//ApplicationContext = new ApplicationContext()
//{
// ReturnUrl = "https://www.example.com",
// CancelUrl = "https://www.example.com"
//}
};
// Call API with your client and get a response for your call
var request = new OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(order);
response = await client().Execute(request);
var statusCode = response.StatusCode;
Order result = response.Result<Order>();
Debug.WriteLine($"Status: {result.Status}");
Debug.WriteLine($"Order Id: {result.Id}");
Debug.WriteLine($"Intent: {result.CheckoutPaymentIntent}");
Debug.WriteLine("Links:");
foreach (LinkDescription link in result.Links)
{
Debug.WriteLine($"\t{link.Rel}: {link.Href}\tCall Type: { link.Method}");
}
return response;
}
}
}
And this is currently called from my Orders controller when an order is completed. This is just for testing purposes.
[Authorize]
public async Task<IActionResult> CompleteOrder()
{
var items = _shoppingCart.GetShoppingCartItems();
Models.Order order = await _ordersService.StoreOrderAsync(items);
PrepareSellerEmail(items, order, "You Have a New Order!");
PrepareBuyerEmail(items, order, "Thank You for Your Order!");
await _shoppingCart.ClearShoppingCartAsync(_serviceProvider);
DeleteCartIDCookie();
//OrderRequest request = Helpers.CreateOrderSample.BuildRequestBody("USD", "100.00", "sb-r43z1e9186231#business.example.com");
//var client = Helpers.Paypal.CaptureOrderSample.client();
var result = Helpers.Paypal.CaptureOrderSample.createOrder("sb-r43z1e9186231#business.example.com");
//var response = await PayPalClient.client().execute.(request);
return View("OrderCompleted");
}
The output of the result is:
Status: CREATED
Order Id: 51577255GE4475222
Intent: CAPTURE
Links:
self: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222 Call Type: GET
approve: https://www.sandbox.paypal.com/checkoutnow?token=51577255GE4475222 Call Type: GET
update: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222 Call Type: PATCH
capture: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222/capture Call Type: POST
This is a screen capture from my sandbox account:
Am I supposed to do something else to actually execute the transfer?
Edit: I figured out how to use the Paypal Payouts API.
First I installed the Nuget Package. It's simply called PayoutsSdk. I'm using version 1.1.1.
For the payout to execute, you need the client() method that is listed above in this post, and this CreatePayout() method listed below.
public async static Task<HttpResponse> CreatePayout()
{
var body = new CreatePayoutRequest()
{
SenderBatchHeader = new SenderBatchHeader()
{
EmailMessage = "Congrats on recieving 1$",
EmailSubject = "You recieved a payout!!"
},
Items = new List<PayoutItem>()
{
new PayoutItem()
{
RecipientType="EMAIL",
Amount=new Currency()
{
CurrencyCode="USD",
Value="1",
},
Receiver="sb-r43z1e9186231#business.example.com",
}
}
};
PayoutsPostRequest request = new PayoutsPostRequest();
request.RequestBody(body);
var response = await client().Execute(request);
var result = response.Result<CreatePayoutResponse>();
Debug.WriteLine($"Status: {result.BatchHeader.BatchStatus}");
Debug.WriteLine($"Batch Id: {result.BatchHeader.PayoutBatchId}");
Debug.WriteLine("Links:");
foreach (PayoutsSdk.Payouts.LinkDescription link in result.Links)
{
Debug.WriteLine($"\t{link.Rel}: {link.Href}\tCall Type: {link.Method}");
}
return response;
}
Of course I'll add parameters to the method for email, amount, currency code, email message, and subject.
Right now, I am calling this method from the controller method like this: var result = Helpers.Paypal.CaptureOrderSample.CreatePayout(); where Helpers.Paypal are folders that contain a class called CaptureOrderSample, which I will probably rename.
To send money from your account to another account, there are several different options:
Automate the sending with the Payouts API or Payouts Web (spreadsheet upload). For live, payouts can only be used if the live account sending the payment is approved for payouts.
Log into the account that is going to send the money in https://www.paypal.com or https://www.sandbox.paypal.com and click on the menu for Pay & Get Paid -> Send Money .
Use a PayPal Checkout integration, with or without the Orders API, and specify a payee that is to receive the money. You must log in with the paying (sending) account to approve the sending, and finally the order must be captured (via API or client side actions.order.capture()) which is what results in a PayPal transaction. If the final capture step is not performed, no money will be sent and the order will merely remain created or approved and eventually expire (72 hours after creation or 3 hours after approval)
In the sandbox, no actual emails are sent with notifications. Instead, the developer.paypal.com dashboard has a "Notifications" tab on the left, and of course activity will also be visible in each sandbox account by logging into the account. Only captured activity is likely to be visible.
Is it possible to trigger recurring payments (subscriptions / billing agreements) using checkout.js?
If so, can you please provide a working example?
Yes its possible. I just created a POC for this.
Create a BillingPlan and activate it
plan = Plan.new(PlanAttributes)
plan.create
patch = Patch.new
patch.op = "replace"
patch.path = "/";
patch.value = { :state => "ACTIVE" }
plan.update( patch )
inside the payment function of paypal.Button call your server to create a BillingAgreement. The user will then authorize the payment.
agreement = Agreement.new(agreement_attributes)
agreement.plan = Plan.new( :id => "<the_plan_id>" )
agreement.create
inside the onAuthorize function of paypal.Button call your server to execute the BillingAgreement
agreement.execute
Following the example in
Checkout https://github.com/chibeepatag/paypal_poc
Is it possible to allow partial payments using the PayPal Invoicing SDK?
I have tried setting the allowPartialPayments attribute to true on the InvoiceType object(see below) although once the invoice has been received there is no option to change the amount being paid.
InvoiceItemListType itemList = new InvoiceItemListType(invoiceItemList);
InvoiceType invoice = new InvoiceType(_MerchantEmailAddress, payerEmailAddress, itemList, "GBP");
invoice.number = brightStartInvoiceId.ToString();
invoice.merchantMemo = brightStartChildId.ToString();
invoice.allowPartialPayments = true;
CreateAndSendInvoiceRequest requestCreateAndSendInvoice = new CreateAndSendInvoiceRequest(envelopeRequest, invoice);