简体   繁体   中英

how to simulate payment denial in paypal sandbox

I created a sandbox personal account with 0 funds but when I went through the payment in my application against sandbox paypal, it still accepted the payment successfully. How do I simulate a denial in payment?

NOTE: It keeps reverting to other payment methods instead of using paypal funds. It has chase manhattan bank and some dicover card setup for some reason in the sandbox account.

code for requesting initial token

    BasicAmountType orderTotal = create(12, false);

    AddressType addr = new AddressType();
    addr.setPhone(user.getPhone());
    addr.setName(user.getName());

    PaymentDetailsType paymentDetails = new PaymentDetailsType();
    paymentDetails.setPaymentAction(PaymentActionCodeType.fromValue("Sale"));
    paymentDetails.setOrderTotal(orderTotal);
    paymentDetails.setFulfillmentAddress(addr);

    List<PaymentDetailsType> paymentDetailsList = new ArrayList<PaymentDetailsType>();
    paymentDetailsList.add(paymentDetails);

    SetExpressCheckoutRequestDetailsType setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType();

    Map<String, Object> map = new HashMap<>();
    String baseUrl = request.getBase();
    String url = baseUrl+Router.reverse("wizards.Setup.confirm", map).url;
    String url2 = baseUrl+Router.reverse("wizards.Setup.cancelled", map).url;

    setExpressCheckoutRequestDetails.setReturnURL(url);
    setExpressCheckoutRequestDetails.setCancelURL(url2);
    setExpressCheckoutRequestDetails.setPaymentDetails(paymentDetailsList);
    setExpressCheckoutRequestDetails.setLocaleCode(getLangCode());
    setExpressCheckoutRequestDetails.setBuyerEmail(user.getEmail());

    BillingAgreementDetailsType billingAgreement = new BillingAgreementDetailsType(BillingCodeType.fromValue("RecurringPayments"));

    String desc = Messages.get("paypal.product.description");
    billingAgreement.setBillingAgreementDescription(desc);
    List<BillingAgreementDetailsType> billList = new ArrayList<BillingAgreementDetailsType>();
    billList.add(billingAgreement);
    setExpressCheckoutRequestDetails.setBillingAgreementDetails(billList);

    SetExpressCheckoutRequestType setExpressCheckoutRequest = new SetExpressCheckoutRequestType(setExpressCheckoutRequestDetails);
    setExpressCheckoutRequest.setVersion(VERSION);  
    setExpressCheckoutRequest.setErrorLanguage(getLangCode());

    SetExpressCheckoutReq setExpressCheckoutReq = new SetExpressCheckoutReq();
    setExpressCheckoutReq.setSetExpressCheckoutRequest(setExpressCheckoutRequest);

    Map<String, String> sdkConfig = Utility.getPaypalSdk();
    PayPalAPIInterfaceServiceService service = new PayPalAPIInterfaceServiceService(sdkConfig);
    try {
        SetExpressCheckoutResponseType response = service.setExpressCheckout(setExpressCheckoutReq);
        AckCodeType ack = response.getAck();
        if(ack == AckCodeType.SUCCESS)
            return response.getToken();
        else if(ack == AckCodeType.SUCCESSWITHWARNING) {
            log.warn("warning on start checkout="+response.getErrors()+", ack="+ack+", token="+response.getToken()+", version="+response.getVersion()+" corrId="+response.getCorrelationID());
            return response.getToken();
        }

        throw new RuntimeException("failed to start checkout="+response.getErrors()+", ack="+ack+", token="+response.getToken()+", version="+response.getVersion()+" corrId="+response.getCorrelationID());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

once paypal redirects back, this is my code to get initial and recurring payment setup

private static CreateRecurringPaymentsProfileResponseDetailsType collectPayment(String token,
        PayPalAPIInterfaceServiceService service, StoreEmployeeDbo emp)
        throws Exception {
    BasicAmountType amount = create(PRICE, true);
    ActivationDetailsType activationDetails = new ActivationDetailsType();
    activationDetails.setFailedInitialAmountAction(FailedPaymentActionType.CANCELONFAILURE);
    activationDetails.setInitialAmount(amount);

    BasicAmountType periodAmt = create(PRICE, false);
    BillingPeriodDetailsType paymentPeriod = new BillingPeriodDetailsType();
    paymentPeriod.setAmount(periodAmt);
    paymentPeriod.setBillingFrequency(1);
    paymentPeriod.setBillingPeriod(BillingPeriodType.MONTH);

    String desc = Messages.get("paypal.product.description");
    ScheduleDetailsType scheduleDetails = new ScheduleDetailsType(desc, paymentPeriod);
    scheduleDetails.setActivationDetails(activationDetails);
    scheduleDetails.setMaxFailedPayments(3);

    DateTime dt = new DateTime();
    DateTime plusMonths = dt.plusMonths(1);
    String dateStr = ""+plusMonths;
    RecurringPaymentsProfileDetailsType recurringDetails = new RecurringPaymentsProfileDetailsType();
    recurringDetails.setBillingStartDate(dateStr);
    recurringDetails.setSubscriberName(emp.getName());

    CreateRecurringPaymentsProfileRequestDetailsType profileReq = new CreateRecurringPaymentsProfileRequestDetailsType();
    profileReq.setToken(token);
    profileReq.setScheduleDetails(scheduleDetails);
    profileReq.setRecurringPaymentsProfileDetails(recurringDetails);

    CreateRecurringPaymentsProfileRequestType reqType = new CreateRecurringPaymentsProfileRequestType();
    reqType.setVersion(VERSION);
    reqType.setErrorLanguage(getLangCode());
    reqType.setCreateRecurringPaymentsProfileRequestDetails(profileReq);

    CreateRecurringPaymentsProfileReq req = new CreateRecurringPaymentsProfileReq();
    req.setCreateRecurringPaymentsProfileRequest(reqType);
    CreateRecurringPaymentsProfileResponseType response = service.createRecurringPaymentsProfile(req );

    AckCodeType ack = response.getAck();
    if(ack == AckCodeType.SUCCESSWITHWARNING) {
        log.warn("warning on start checkout="+response.getErrors()+", ack="+ack+", version="+response.getVersion()+" corrId="+response.getCorrelationID());             
        if(response.getCreateRecurringPaymentsProfileResponseDetails() != null) {
            CreateRecurringPaymentsProfileResponseDetailsType details = response.getCreateRecurringPaymentsProfileResponseDetails();
            log.warn("more info.  profileid="+details.getProfileID()+" txid="+details.getTransactionID()+" status="+details.getProfileStatus().getValue());
        }
        return response.getCreateRecurringPaymentsProfileResponseDetails();
    } else if(ack == AckCodeType.SUCCESS) {
        return response.getCreateRecurringPaymentsProfileResponseDetails();
    }

    throw new RuntimeException("failure collecting payment="+response.getErrors()+", ack="+ack+", version="+response.getVersion()+" corrId="+response.getCorrelationID());
}

yet this was succeeding.

EDIT: I turned on negative testing and when I request the paypal token, I set the amount to 105.37 (I tried USD and HKD but neither helps)....

            //In this code, t7he orderTotal is 105.37 in USD (this is part of the request payment token code
    PaymentDetailsType paymentDetails = new PaymentDetailsType();
    paymentDetails.setPaymentAction(PaymentActionCodeType.fromValue("Sale"));
    paymentDetails.setOrderTotal(orderTotal);
    paymentDetails.setFulfillmentAddress(addr);

Then when user clicks purchase, I set up the recurring profile and insert 105.37 into the intial amount AND the recurring amount in the following code.....

            //amount variable AND periodAmt variable are setup with 105.37 in USD
    ActivationDetailsType activationDetails = new ActivationDetailsType();
    activationDetails.setFailedInitialAmountAction(FailedPaymentActionType.CANCELONFAILURE);
    activationDetails.setInitialAmount(amount);

    BillingPeriodDetailsType paymentPeriod = new BillingPeriodDetailsType();
    paymentPeriod.setAmount(periodAmt);
    paymentPeriod.setBillingFrequency(1);
    paymentPeriod.setBillingPeriod(BillingPeriodType.MONTH);

The payment still succeeds just fine :(

The soap message sent from above is

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="urn:ebay:api:PayPalAPI" xmlns:ebl="urn:ebay:apis:eBLBaseComponents" 
xmlns:cc="urn:ebay:apis:CoreComponentTypes" xmlns:ed="urn:ebay:apis:EnhancedDataTypes">
<soapenv:Header><ns:RequesterCredentials><ebl:Credentials><ebl:Username>dean-facilitator_api1.xsoftware.biz</ebl:Username>
<ebl:Password>138807XXXX</ebl:Password>    
<ebl:Signature>AY.QZJbiiP6AK3cWhljHCEhQtTyzApzADFFNYBR</ebl:Signature></ebl:Credentials>
</ns:RequesterCredentials></soapenv:Header><soapenv:Body>   
<ns:CreateRecurringPaymentsProfileReq><ns:CreateRecurringPaymentsProfileRequest>
<ebl:ErrorLanguage>zh_CN</ebl:ErrorLanguage><ebl:Version>104.0</ebl:Version>
<ebl:CreateRecurringPaymentsProfileRequestDetails>
<ebl:Token>EC-0KU028910G908352C</ebl:Token>
<ebl:RecurringPaymentsProfileDetails><ebl:SubscriberName>wert</ebl:SubscriberName><ebl:BillingStartDate>2014-01-29T12:06:17.004-07:00</ebl:BillingStartDate></ebl:RecurringPaymentsProfileDetails><ebl:ScheduleDetails>
<ebl:Description>You will be billed monthly while your store is online and live.  You can cancel and close your store at any time.</ebl:Description><ebl:PaymentPeriod><ebl:BillingPeriod>Month</ebl:BillingPeriod>
<ebl:BillingFrequency>1</ebl:BillingFrequency><ebl:Amount currencyID="USD">105.37</ebl:Amount></ebl:PaymentPeriod>
<ebl:MaxFailedPayments>3</ebl:MaxFailedPayments>
<ebl:ActivationDetails><ebl:InitialAmount currencyID="USD">105.37</ebl:InitialAmount>
<ebl:FailedInitialAmountAction>CancelOnFailure</ebl:FailedInitialAmountAction>
</ebl:ActivationDetails></ebl:ScheduleDetails>
</ebl:CreateRecurringPaymentsProfileRequestDetails>
</ns:CreateRecurringPaymentsProfileRequest></ns:CreateRecurringPaymentsProfileReq>

thanks, Dean

Log in to your account at http://developer.paypal.com and then click into Applications, and then Sandbox accounts on the left. You'll see your sandbox accounts there, and each will have a little arrow that you can click to get extra options. Click the arrow, and then click Profile. Once the profile pops up click Settings, and then turn Negative Testing on.

With negative testing enabled on the sandbox account you can force specific error codes by sending the amount that matches the code. For example, if you want to trigger error 10537 you'd send the AMT of 105.37 in your API request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM