DPRP is disabled for this merchant. Paypal Error - c#

I am trying to Create a billing agreement with payment method:credit card.
Here is my code:
public void CreateBillingAgreement()
{
var config = ConfigManager.Instance.GetProperties();
var accessToken = new OAuthTokenCredential(config).GetAccessToken();
var apiContext = new APIContext(accessToken);
//Note: Billing agreements for credit card payments execute automatically when created. There is no need for the user to approve the agreement or to execute the agreement.
var 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",
first_name = "Test",
last_name = "abc",
expire_month = **,
expire_year = ****,
number = "********",
type = "visa"
};
List<FundingInstrument> funding_instruments = new List<FundingInstrument>();
var fund = new FundingInstrument
{
credit_card = credit_card
};
funding_instruments.Add(fund);
var payer = new Payer
{
payment_method = "credit_card",
funding_instruments = funding_instruments
};
var shipping_address = new ShippingAddress
{
line1 = "1234",
city = "California",
state = "California",
postal_code = "95070",
country_code = "US"
};
string Date = DateTime.Now.ToString("yyyy-MM-ddTHH:MM:ssZ");
//Make API call
var agreement = new Agreement
{
name = "T-Shirt of the Month Club Agreement",
description = "Agreement for T-Shirt of the Month Club Plan",
start_date = Date,
plan = new Plan
{
id = "P-*****************"
},
payer = payer,
shipping_address = shipping_address
};
var CreateExecuteAgreement = agreement.Create(apiContext);
But getting this error,
//{"name":"DPRP_DISABLED","message":"DPRP is disabled for this
merchant.","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#DPRP_DISABLED","debug_id":"********"}
}

DPRP = DirectPayment Recurring Payments. This is very specific.
To use this you would need to be using "PayPal Website Payments Pro 3.0", where you would typically use the DoDirectPayment API to process credit cards, and that is $30/mo.
On top of that, you need to add Recurring Payments, and then you would use the CreateRecurringPaymentsProfile API with credit card details included directly (which must be what this SDK you're using is doing). This is considered DPRP, and this is an additional $30/mo on top of the fee for Pro.
Many people get confused because if you sign up for "Payments Pro Recurring Billing" they will probably put you into the PayFlow version, in which case you would need to use the PayFlow API instead of DoDirectPayment / CreateRecurringPaymentsProfile.
So the first thing you need to do is very which version of Payments Pro you are using, and then verify whether or not you have Recurring Payments / Billing enabled on top of that.

Related

How long is a Stripe Checkout session valid for?

I'm creating a Stripe Checkout session via the C# SDK and wish to know how long the session will be valid for.
var options = new SessionCreateOptions
{
SuccessUrl = "https://example.com/success.html?session_id={CHECKOUT_SESSION_ID}",
CancelUrl = "https://example.com/canceled.html",
PaymentMethodTypes = new List<string>
{
"card",
},
Mode = "subscription",
LineItems = new List<SessionLineItemOptions>
{
new SessionLineItemOptions
{
Price = req.PriceId,
Quantity = 1,
},
},
};
var service = new SessionService();
var session = await service.CreateAsync(options);
Stripe Checkout Sessions expire 24 hours after creation.
Source: https://stripe.com/docs/payments/accept-a-payment

How do you preview a proration using Stripe.NET?

I'm following the example provided in the Stripe documentation on Previewing Proration using the Stripe.NET library to try to find the amount that will be charged when a customer upgrades from Plan A to Plan B.
However, when I use the code sample in the documentation, I get an error:
UpcomingInvoiceOptions options = new UpcomingInvoiceOptions()
{
CustomerId = "cus_XXXXXXXXXXXXX",
SubscriptionProrationDate = DateTime.UtcNow,
SubscriptionItems = new List<InvoiceSubscriptionItemOptions>()
{
new InvoiceSubscriptionItemOptions()
{
Id = "si_XXXXXXXXXXXXXX", // Current Sub Item
PlanId = "plan_XXXXXXXXXXXX" // New plan
}
}
};
InvoiceService service = new InvoiceService();
var result = service.Upcoming(options);
The last line throws a Stripe.StripeException: You cannot update a subscription item without a subscription.
Turns out options.SubscriptionId is a required field for this action if you don't call service.Get first.
The following code produces the correct results:
UpcomingInvoiceOptions options = new UpcomingInvoiceOptions()
{
CustomerId = "cus_XXXXXXXXXXXXX",
SubscriptionId = "sub_XXXXXXXXXXXX",
SubscriptionProrationDate = DateTime.UtcNow,
SubscriptionItems = new List<InvoiceSubscriptionItemOptions>()
{
new InvoiceSubscriptionItemOptions()
{
Id = "si_XXXXXXXXXXXXXX", // Current Sub Item
PlanId = "plan_XXXXXXXXXXXX" // New plan
}
}
};
InvoiceService service = new InvoiceService();
var result = service.Upcoming(options);

Stripe exception thrown when creating new connect account with bank account

After upgrading to the latest version of Stripe.Net.
I'm trying to create a new custom connect account, which includes a bank account, with the .Net API and Stripe is throwing this exception.
This account can only be updated with an account token, because it was originally created with an account token. (Attempted to update param 'account_token' directly.)
I'm assigning the AccountToken I'm generating from Stripe.js and that seems to be generating ok. Additionally I have no issue adding an external bank to a already created connect account. I just can't seem to create a new custom account
Here is my c# code
AccountDobOptions dobOptions = new AccountDobOptions()
{
Day = yogaProfile.Birthdate.Day,
Month = yogaProfile.Birthdate.Month,
Year = yogaProfile.Birthdate.Year
};
AddressOptions addressOptions = new AddressOptions()
{
City = bankDetails.City,
Country = bankDetails.CountryCode,
State = bankDetails.CountryCode == "US" ? bankDetails.USStateCode : bankDetails.NonUSStateCode,
PostalCode = bankDetails.PostalCode,
Line1 = bankDetails.AddressLine1,
Line2 = bankDetails.AddressLine2
};
AccountLegalEntityOptions legal = new AccountLegalEntityOptions();
legal.Dob = dobOptions;
legal.Type = "individual";
legal.Address = addressOptions;
legal.FirstName = accountFullName.Split(' ')[0];
legal.LastName = accountFullName.Split(' ')[1];
//legal.SSNLast4 = bankDetails.LastFourSSN;
AccountTosAcceptanceOptions tosOptions = new AccountTosAcceptanceOptions()
{
Date = DateTime.UtcNow,
Ip = clientIpAddress != null ? clientIpAddress : GetUserIpAddress()
};
var accountOptions = new AccountCreateOptions()
{
Email = yogaProfile.ApplicationUser.Email,
Type = AccountType.Custom,
Country = bankDetails.CountryCode,
LegalEntity = legal,
TosAcceptance = tosOptions,
AccountToken = stripeToken,
//TransferScheduleInterval = "weekly",
ExternalBankAccount = new AccountBankAccountOptions()
};
var accountService = new AccountService();
Account account = accountService.Create(accountOptions);

Authorized.net - Can createTransactionRequest be use for Authorize, capture and void a transaction for existing payment profile id

For customer with existing payment profile id(Saved credit card) we are using "createCustomerProfileTransactionController" as follow for authorization.
public createCustomerProfileTransactionResponse AuthorizePaymentProfile(int customerProfileId, int customerPaymentProfileId, decimal amount)
{
createCustomerProfileTransactionResponse response = null;
ApiOperationBase<ANetApiRequest, ANetApiResponse>.RunEnvironment = environment;
// define the merchant information (authentication / transaction id)
ApiOperationBase<ANetApiRequest, ANetApiResponse>.MerchantAuthentication = new merchantAuthenticationType()
{
name = apiLoginID,
ItemElementName = ItemChoiceType.transactionKey,
Item = apiTransactionKey,
};
//construct request
var request = new createCustomerProfileTransactionRequest
{
merchantAuthentication = new merchantAuthenticationType
{
name = apiLoginID,
ItemElementName = ItemChoiceType.transactionKey,
Item = apiTransactionKey
},
transaction = new profileTransactionType
{
Item = new profileTransAuthOnlyType
{
customerProfileId = customerProfileId.ToString(),
customerPaymentProfileId = customerPaymentProfileId.ToString(),
amount = amount
}
},
extraOptions = "x_duplicate_window=1"
};
//Prepare Request
var controller = new createCustomerProfileTransactionController(request);
controller.Execute();
//Send Request to EndPoint
response = controller.GetApiResponse();
return response;
}
And for customer without existing payment profile id we using "createTransactionRequest" as follow for authorization.
public createTransactionResponse AuthorizeOneTimePayment(Card cardInfo, decimal amount)
{
createTransactionResponse response = null;
ApiOperationBase<ANetApiRequest, ANetApiResponse>.RunEnvironment = environment;
//define the merchant information (authentication / transaction id)
ApiOperationBase<ANetApiRequest, ANetApiResponse>.MerchantAuthentication = new merchantAuthenticationType()
{
name = apiLoginID,
ItemElementName = ItemChoiceType.transactionKey,
Item = apiTransactionKey,
};
var creditCard = new creditCardType
{
cardNumber = cardInfo.CardNumber,// "4111111111111111",
expirationDate = cardInfo.ExpirationDate// "0718"
//cardCode=cardInfo.VerificationCode
};
//standard api call to retrieve response
var paymentType = new paymentType { Item = creditCard };
string firstName = string.Empty;
string lastName = string.Empty;
if (!string.IsNullOrWhiteSpace(cardInfo.BillingName))
{
string[] name = GetBillName(cardInfo.BillingName);
firstName = name[0];
lastName = name[1];
}
var transactionRequest = new transactionRequestType
{
transactionType = transactionTypeEnum.authOnlyTransaction.ToString(), // authorize only
amount = amount,
payment = paymentType,
billTo = new customerAddressType
{
firstName = firstName,
lastName = lastName,
address = cardInfo.BillingAddress,
city = cardInfo.BillingCity,
state = cardInfo.BillingState,
zip = cardInfo.BillingZipCode
}
};
var request = new createTransactionRequest { transactionRequest = transactionRequest };
// instantiate the controller that will call the service
var controller = new createTransactionController(request);
controller.Execute();
// get the response from the service (errors contained if any)
response = controller.GetApiResponse();
return response;
}
And following same technique for capture and void a transaction.
My question is can we use "createTransactionRequest" for all transaction like authorize, capture and void a transaction for both customer having payment profile id and one time customer.
I could find any clue in authorize.net on line documentation. Please guide us how to do that.
Yes, you can use createTransactionRequest for Auth/Capture, Auth Only, Prior Auth and Capture, Void and Refund by changing the transactionRequestType and paymentType.
For anyone with the same question, like me, here is the answer.
Note that Order is optional, and obviously profile is optional.
...
var transactionRequest = new transactionRequestType {
transactionType = transactionTypeEnum.authOnlyTransaction.ToString(),
amount = amount,
order = new orderType { invoiceNumber = OrderID, description = desc },
profile = getCustomerPaymentProfile(CustomerProfileId, creditProfileID)
};
...
private customerProfilePaymentType getCustomerPaymentProfile(string CustomerProfileId, string creditProfileID) {
return new customerProfilePaymentType {
customerProfileId = CustomerProfileId,
paymentProfile = new paymentProfile { paymentProfileId = creditProfileID }
};
}

Return JSON as a response for HTTP Get in ASP.NET WebApi Controller

Can I collect few variables and list and put it into JSON, that will be returned to client if HTTP Get call is successful?
For example:
I have this Controller that has to return list of accounts, and few more values:
public class BankAccountController : ApiController
{
[Authorize]
[Route("/accounts")]
public IHttpActionResult GetAccounts()
{
List<Account> userAccounts = new List<Account>{
new Account {
AccountNumber = 1,
Available = 2346.220m,
Balance = 3219.12m,
Currency = "euro",
InterestRate = 1,
Name = "Current account",
Type = ""},
new Account {
AccountNumber = 2,
Available = 12346.220m,
Balance = 32219.12m,
Currency = "euro",
InterestRate = 3,
Name = "Saving account",
Type = ""},
new Account {
AccountNumber = 3,
Available = 346.220m,
Balance = 219.12m,
Currency = "euro",
InterestRate = 3,
Name = "Current account",
Type = ""},
new Account {
AccountNumber = 4,
Available = 37846.220m,
Balance = 21943.12m,
Currency = "euro",
InterestRate = 3,
Name = "Saving account",
Type = ""},
new Account {
AccountNumber = 5,
Available = 137846.220m,
Balance = 21943.12m,
Currency = "euro",
InterestRate = 3,
Name = "Saving account",
Type = ""},
new Account {
AccountNumber = 6,
Available = 7846.220m,
Balance = 21943.12m,
Currency = "euro",
InterestRate = 3,
Name = "Current account",
Type = ""}
};
var currentAccountsTotal = userAccounts.Count();
string currentsAccountTotalCurrency = "something";
string savingsAccountTotalCurrency = "something";
decimal savingsAccountsTotal = userAccounts.Where(a => a.Name == "Saving account").Select(b => b.Balance).Sum();
return ?;
}
Can I take userAccounts list, currentAccountsTotal, currentsAccountTotalCurrency , savingsAccountsTotal and put them into some JSON that will be returned to client?
I have call specification and it looks like this: On 200 code I return all mentioned in JSON to client.
What should I put as return value in this case?
What you need to know:
Out of the box, webapi supports the notion of content negotiation.
What is content negotiation?
Content negotiation is the process of selecting the best representation (JSON, XML, etc).
How is it done in WebAPI?
Basically, it is reading the accept header.
Example:
Accept: application/xml
If the webapi finds any formatter for that request, it will format the response as the user requested.
You can add or remove formatters, for example, if you want always json, we should remove the xml formatter, like this:
config.Formatters.Remove(config.Formatters.XmlFormatter);
You can also create your own formatter if you need and add it to the configuration.
At the code, you only need to return your object or Ok() depending on what are you using as return type.
In your case, we can use a anonymous object or you can request your own DTO to represent your response, that includes the three objects together.

Categories