Braintree не генерирует клиентский токен на эластичном бобовом стебле AWS

Я столкнулся с этой проблемой в приложении Spring Boot, где я получаю исключение нулевого указателя для генерации клиентского токена для Braintree на AWS Elastic Beanstalk, где он отлично работает в localhost. Если кто-нибудь может помочь мне указать на проблему, которая будет высоко оценена.

проект

KolystyleApplication.java

package com.kolystyle;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

@SpringBootApplication
public class KolystyleApplication extends SpringBootServletInitializer {

    public static String DEFAULT_CONFIG_FILENAME = "config.properties";
    public static BraintreeGateway gateway;

     public static void main(String[] args) throws Exception {
           File configFile = new File(DEFAULT_CONFIG_FILENAME);

        try {
            if(configFile.exists() && !configFile.isDirectory()) {
                gateway = BraintreeGatewayFactory.fromConfigFile(configFile);

                System.out.println("Braintree API use From Config File");
            } else {
                gateway = BraintreeGatewayFactory.fromConfigMapping(System.getenv());
                System.out.println("Braintree configuration from SYSTEM ENVIRONMENT loaded");

            }
        } catch (NullPointerException e) {
            System.err.println("Could not load Braintree configuration from config file or system environment.");
            System.exit(1);
        }
        SpringApplication.run(KolystyleApplication.class, args);
    }
        }

     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
            return builder.sources(KolystyleApplication.class);
        }

}

BraintreeGatewayFactory.java

package com.kolystyle;

import com.braintreegateway.BraintreeGateway;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.util.Map;
import java.util.Properties;

public class BraintreeGatewayFactory {
    public static BraintreeGateway fromConfigMapping(Map<String, String> mapping) {
        return new BraintreeGateway(
            mapping.get("BT_ENVIRONMENT"),
            mapping.get("BT_MERCHANT_ID"),
            mapping.get("BT_PUBLIC_KEY"),
            mapping.get("BT_PRIVATE_KEY")
        );
    }

    public static BraintreeGateway fromConfigFile(File configFile) {
        InputStream inputStream = null;
        Properties properties = new Properties();

        try {
            inputStream = new FileInputStream(configFile);
            properties.load(inputStream);
        } catch (Exception e) {
            System.err.println("Exception: " + e);
        } finally {
            try { inputStream.close(); }
            catch (IOException e) { System.err.println("Exception: " + e); }
        }

        return new BraintreeGateway(
            properties.getProperty("BT_ENVIRONMENT"),
            properties.getProperty("BT_MERCHANT_ID"),
            properties.getProperty("BT_PUBLIC_KEY"),
            properties.getProperty("BT_PRIVATE_KEY")
        );
    }
}

config.properties

BT_ENVIRONMENT=sandbox
BT_MERCHANT_ID=some_merchant_id
BT_PUBLIC_KEY=some_public_key
BT_PRIVATE_KEY=some_private_id

CheckoutController.java

     package com.kolystyle.controller;

 <removed imports to meet 30000 characters limit>

    import com.braintreegateway.BraintreeGateway;
    import com.braintreegateway.Result;
    import com.braintreegateway.Transaction;
    import com.braintreegateway.TransactionRequest;
    import com.braintreegateway.ValidationError;
    import com.braintreegateway.Transaction.Status;
    import com.kolystyle.KolystyleApplication;
    import com.kolystyle.domain.BillingAddress;

    import com.kolystyle.service.PaymentService;
    import com.kolystyle.utility.MailConstructor;
    import com.kolystyle.utility.USConstants;

    @Controller
    public class CheckoutController {
        private static final Logger LOG = LoggerFactory.getLogger(CheckoutController.class);
        private BraintreeGateway gateway = KolystyleApplication.gateway;

        private Status[] TRANSACTION_SUCCESS_STATUSES = new Status[] {
           Transaction.Status.AUTHORIZED,
           Transaction.Status.AUTHORIZING,
           Transaction.Status.SETTLED,
           Transaction.Status.SETTLEMENT_CONFIRMED,
           Transaction.Status.SETTLEMENT_PENDING,
           Transaction.Status.SETTLING,
           Transaction.Status.SUBMITTED_FOR_SETTLEMENT
        };

    private ShippingAddress shippingAddress = new ShippingAddress();
        private BillingAddress billingAddress = new BillingAddress();
        private Payment payment = new Payment();
    @Autowired
        private UserService userService;
        @Autowired
        private OrderRepository orderRepository;
        @Autowired
        private OrderLogRepository orderLogRepository;
        @Autowired
        private ShoppingCartService shoppingCartService;

        @Autowired
        private CartItemService cartItemService;

        @Autowired
        private ShippingAddressService shippingAddressService;

        @Autowired
        private BillingAddressService billingAddressService;

        @Autowired
        private PaymentService paymentService;

        @Autowired
        private UserShippingService userShippingService;

        @Autowired
        private SiteSettingService siteSettingService;

        @Autowired
        private UserPaymentService userPaymentService;

        @Autowired
        private OrderService orderService;

        @Autowired
        private OrderLogService orderLogService;

        @Autowired
        private PromoCodesService promoCodesService;
        @Autowired
        private PromoCodesRepository promoCodesRepository;

        @RequestMapping("/cart/guestcheckout")
        public String guestcheckout(HttpServletRequest request,HttpServletResponse response,Model model ) {
            SiteSetting siteSettings = siteSettingService.findOne(new Long(1));
            model.addAttribute("siteSettings",siteSettings);
            ShoppingCart shoppingCart;


            shoppingCart = shoppingCartService.findCartByCookie(request);
            System.out.println("SUCCESSFUL WITH COOKIE LOGIC");


            if(shoppingCart == null) {
                return "redirect:/shoppingCart/cart";
            }
            List<CartItem> cartItemList = cartItemService.findByShoppingCart(shoppingCart);
            SiteSetting siteSetting= siteSettingService.findOne((long) 1);
            ShippingAddress shippingAddress = new ShippingAddress();
            BillingAddress billingAddress = new BillingAddress();
            Payment payment = new Payment();
            if(shoppingCart.getShippingMethod().equalsIgnoreCase("premiumShipping")) {
                model.addAttribute("premiumShipping",true);
            }else {
                model.addAttribute("groundShipping",true);
            }
            String clientToken;
             try {
                 clientToken = gateway.clientToken().generate();
                 LOG.info("Client token {} for paypal generated",clientToken);
               } catch (Exception e) {
                   System.out.println("Exception: " + e);

                   return "badRequestPage";
               }

            System.out.println("ClientToken: "+clientToken);
            model.addAttribute("siteSetting", siteSetting);
            model.addAttribute("clientToken", clientToken);
            model.addAttribute("shippingAddress",shippingAddress);
            model.addAttribute("payment",payment);
            model.addAttribute("billingAddress",billingAddress);
            model.addAttribute("cartItemList",cartItemList);
            model.addAttribute("shoppingCart",shoppingCart);
            List<String> stateList = USConstants.listOfUSStatesCode;
            Collections.sort(stateList);
            model.addAttribute("stateList", stateList);
            model.addAttribute("noCartExist",true);
            return "guestcheckout";

        }

guestcheckout.html

  <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head th:replace="common/head :: common-head" />
<body>
<!-- Load the required components. -->
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script src="https://js.braintreegateway.com/web/3.25.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.25.0/js/paypal-checkout.min.js"></script>
<div class="spinnerspin">
    <div class="wrapper-box">
        <div class="main-wrapper">

            <div th:replace="common/head :: navbar" />

            <div id="container">
                <div id="content">          
        <section class="" ng-app="checkoutApp">
        <div ng-controller = "checkoutCtrl" th:attr="ng-init='initCartId('+${shoppingCart.id}+')'">         

        <div class="row" style="margin-top: 10px;">

            <form th:action="@{/chargeguest}" method="post" id="payment-form">
            <!--form th:action="@{/checkouts}" method="post" id="payment-form"-->
                <!-- Checkout Info -->
                <div class="col-md-12">
                    <div th:if="${missingRequiredField}">
                        <h5 class="alert alert-warning">There are some fields
                            missing. Field with * is required</h5>
                    </div>
                </div>
                <div class="col-md-6">
                <div class="panel-group" id="accordion">

                    <div class="col-md-12">

                        <!-- 1. Shipping Address -->
                        <div class="panel panel-default">
                            <div class="panel-heading">
                                <h4 class="panel-title">
                                    <a data-toggle="collapse" data-parent="#accordion"
                                        href="#shippingInfo">Shipping Address</a>
                                </h4>
                            </div>
                            <div id="shippingInfo" class="panel-collapse collapse in"
                                th:classappend="${classActiveShipping}? 'in'">
                                <div class="panel-body">
                                    <div class="row">

                                        <div class="col-md-6">
                                    <div class="form-group">

                                        <label for="firstName">* First Name</label> <input type="text"
                                            class="form-control" id="firstName"
                                            placeholder="First Name" th:name="firstName"
                                            required="required"
                                            th:value="${shippingAddress.firstName}" />
                                    </div>
                                    </div>
                                    <div class="col-md-6">
                                    <div class="form-group">

                                        <label for="lastName">* Last Name</label> <input type="text"
                                            class="form-control" id="lastName"
                                            placeholder="Last Name" th:name="lastName"
                                            required="required"
                                            th:value="${shippingAddress.lastName}" />
                                    </div>
                                    </div>
                                    </div>

                                    <div class="form-group">
                                        <label for="shippingStreet">* Street Address</label> <input
                                            type="text" class="form-control" id="shippingAddressStreet1"
                                            placeholder="Street Address 1"
                                            th:name="shippingAddressStreet1" required="required"
                                            th:value="${shippingAddress.shippingAddressStreet1}" />
                                    </div>
                                    <div class="form-group">
                                        <input type="text" class="form-control"
                                            placeholder="Street Address 2"
                                            th:name="shippingAddressStreet2"
                                            th:value="${shippingAddress.shippingAddressStreet2}" />
                                    </div>
                                    <div class="form-group">
                                                <label for="shippingCity">* City</label> <input type="text"
                                                    class="form-control" id="shippingAddressCity"
                                                    placeholder="Shipping City" th:name="shippingAddressCity"
                                                    required="required"
                                                    th:value="${shippingAddress.shippingAddressCity}" />
                                            </div>
                                    <div class="row">

                                        <div class="col-xs-6">
                                            <div class="form-group">
                                                <label for="shippingState">* State</label> <select
                                                    id="shippingAddressState" class="form-control"
                                                    th:name="shippingAddressState"
                                                    th:value="${shippingAddress.shippingAddressState}"
                                                    required="required">
                                                    <option value="" disabled="disabled">Please select
                                                        an option</option>
                                                    <option th:each="state : ${stateList}" th:text="${state}"
                                                        th:selected="(${shippingAddress.shippingAddressState}==${state})"></option>
                                                </select>
                                            </div>
                                        </div>
                                        <div class="col-xs-6">
                                            <div class="form-group">
                                                <label for="shippingZipcode">* Zipcode</label> <input
                                                    type="text" class="form-control" id="shippingAddressZipcode"
                                                    placeholder="Shipping Zipcode"
                                                    th:name="shippingAddressZipcode" required="required"
                                                    th:value="${shippingAddress.shippingAddressZipcode}" />
                                            </div>
                                        </div>
                                    </div>

                                    <!-- a data-toggle="collapse" data-parent="#accordion"
                                        class="btn btn-warning pull-right" href="#paymentInfo">Next</a-->

                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="col-md-12">
                    <!-- Shipping Method -->
                        <div class="panel panel-default">
                            <div class="panel-heading">
                                <h4 class="panel-title">
                                    <a data-toggle="collapse" data-parent="#accordion"
                                        href="#shipMethod">Shipping Method</a>
                                </h4>
                            </div>
                            <div id="shipMethod" class="panel-collapse collapse in"
                                th:classappend="${classActiveCustomer}? 'in'">
                                <div class="panel-body">

                                    <h4>Choose your shipping method:</h4>
                        <div class="radio">
                        <label>
                        <input type="radio" th:name="shippingMethod" value="groundShipping" ng-click="changeShippingMethod('groundShipping')" th:checked="${groundShipping}"/>Ground Shipping<br/>
Transit time: 3-6 business days
                        </label>
                        </div>

                        <div class="radio">
                        <label>
                        <input type="radio" th:name="shippingMethod" value="premiumShipping" ng-click="changeShippingMethod('premiumShipping')" th:checked="${premiumShipping}"/>Premium Shipping
                        <span class="text-right"><strong> $<span th:text="${siteSetting.premiumShippingCost}"></span></strong></span><br/>Transit time: 2-3 business days
                        </label>

                        </div>
                                </div>
                            </div>
                        </div>

                    </div>

                    <div class="col-md-12"> 
                        <!--2. Payment Information -->
                        <div class="panel panel-default">
                        <div class="panel-heading">
                        <h4 class="panel-title">
                        <a data-toggle="collapse" data-parent="#accordion" href="#paymentInfo">Payment Information</a>
                        </h4>
                        </div>

                        <div id="paymentInfo" class="panel-collapse collapse in" th:classappend="${classActivePayment}? 'in'">
                            <div class="panel-body">

<div class="col-md-12">     

<div id="sample"></div>




  <div id="payPal" class="">
    <br/>


    <!-- Paypal Amount -->
    <label for="amount">
            <span class="input-label">Amount</span>
            <div class="input-wrapper amount-wrapper">
              <input id="amount" name="amount" type="hidden" min="1" placeholder="Amount" value="{{checkOut.orderTotal}}" />
            </div>
    </label>

    <div class="bt-drop-in-wrapper">
            <div id="bt-dropin"></div>
    </div>

    <input type="hidden" id="nonce" name="payment_method_nonce" />


    <script src="https://js.braintreegateway.com/web/dropin/1.9.2/js/dropin.min.js"></script>
<script th:inline="javascript">
  /*<![CDATA[*/
  var form = document.querySelector('#payment-form');
  var client_token = [[${clientToken}]];
  braintree.dropin.create({
    authorization: client_token,
    // container: '#dropin-container',
    container: '#bt-dropin',
    card: {
        cardholderName: {required: true},
        postalCode: {
          minlength: 5 // Set the minimum length of the postal code field
        },
        cvv:true,
        avs:true
      },
    paypal: {
      flow: 'vault'
    }
  }, function (createErr, instance) {
    form.addEventListener('submit', function (event) {
    event.preventDefault();
    instance.requestPaymentMethod(function (err, payload) {
      if (err) {
        console.log('Error', err);
        return;
      }
      // Add the nonce to the form and submit
      document.querySelector('#nonce').value = payload.nonce;
        form.submit();
      });
    });
  });
 // var checkout = new Demo({
 //   formID: 'payment-form'
//  });
  /*]]>*/
</script>


  </div>

    </div>                              


                        <!--a data-toggle="collapse" data-parent="#accordion" class="btn btn-warning pull-right" href="#reviewItems">Next</a-->

                                    </div>
                                    </div>
                            </div>
                    </div>

                </div>
                </div>
                <!-- 3. Review Items and Shipping -->
                <div class="col-md-6">
                <div class="panel-group" id="accordion">
                    <div class="col-md-12">
                    <!-- Contact Information -->
                        <div class="panel panel-default">
                            <div class="panel-heading">
                                <h4 class="panel-title">
                                    <a data-toggle="collapse" data-parent="#accordion"
                                        href="#customerInfo">Contact Information</a>
                                </h4>
                            </div>
                            <div id="customerInfo" class="panel-collapse collapse in"
                                th:classappend="${classActiveCustomer}? 'in'">
                                <div class="panel-body">

                                    <div class="form-group">

                                        <label for="phoneNumber">* Phone number</label> <input type="text"
                                            class="form-control" id="phoneNumber"
                                            placeholder="Phone number" th:name="phoneNumber"
                                            required="required"
                                            th:value="${shippingAddress.shippingAddressName}" />
                                    </div>
                                    <div class="form-group">
                                        <label for="email">* Email address</label> <input
                                            type="text" class="form-control" id="email"
                                            placeholder="Email Address"
                                            th:name="email" required="required"
                                            th:value="${shippingAddress.shippingAddressStreet1}" />
                                    </div>


                                </div>
                            </div>
                        </div>

                    </div>
                    <div class="col-md-12">
                    <div class="panel panel-default">
                    <div class="panel-heading">
                            <h4 class="panel-title">
                            <a data-toggle="collapse" data-parent="#accordion" href="#reviewItems">Review Items and Shipping</a>
                            </h4>
                        </div>
                    <div id="reviewItems" class="panel-collapse collapse in">
                    <div class="panel-body">


                        <div class="row">
                        <div class="col-xs-6"><h4>Products</h4></div>
                        <div class="col-xs-2"><h4>Price</h4></div>
                        <div class="col-xs-2"><h4>Qty</h4></div>
                        <div class="col-xs-2 text-right"><h4>Amount</h4></div>
                        </div>

                        <!-- Display products in cart -->
                        <div class="row" th:attr="ng-repeat = 'cartItem in checkOut.cartItemList'">

                        <hr/>
                        <div class="col-xs-2">
                        <a th:href="@{/productDetail?id={{cartItem.product.id}}}">
                        <img class="img-responsive shelf-product" th:src="#{adminPath}+@{/image/product/{{cartItem.product.id}}/{{cartItem.product.coverImageName}}}" style="width:70px;" />
                        </a>
                        </div>
                        <div class="col-xs-4">
                            <div style="margin-left:50px;"> 
                            <a th:href="@{/productDetail?id={{cartItem.product.id}}}"><h4>{{cartItem.product.title}}</h4></a>
                                <span>Size: </span><span>{{cartItem.productSize}}</span> | <span>Web ID: </span><span>{{cartItem.product.sku}}</span>
                            </div>
                            </div>
                            <div class="col-xs-2">
                                <h5 style="color: #db3208; font-size: large;">
                                    $<span>{{cartItem.product.ourPrice}}</span>
                                </h5>

                            </div>
                            <div class="col-xs-2">
                                <h5 style="font-size:large">{{cartItem.qty}}</h5>
                            </div>
                            <div class="col-xs-2">

                            <h5 class="text-primary text-right" style="font-size: large;">
                                    $<span>{{(cartItem.product.ourPrice * cartItem.qty).toFixed(2)}}</span>
                                </h5>
                            </div>

                        </div>
                        <hr/>

                            <div class="row">
                                <div class="col-xs-7 text-left">Subtotal :</div>
                                <div class="col-xs-5 text-right">
                                    $<span>{{checkOut.grandTotal.toFixed(2)}}</span>
                                </div>
                            </div>


                            <div class="row">
                                <div class="col-xs-7 text-left">Discount :</div>
                                <div class="col-xs-5 text-right text-danger">
                                    -$<span>{{checkOut.discountedAmount.toFixed(2)}}</span>
                                </div>
                            </div>

                            <div class="row">
                                <div class="col-xs-7 text-left">Shipping : </div>
                                <div class="col-xs-5 text-right text-success">
                                    <span>{{checkOut.shippingCost}}</span>
                                </div>
                            </div>


                            <div class="row">
                                <div class="col-xs-7 text-left">
                                    <h3 style="color: darkred;">
                                        <strong>Order Total : </strong>
                                    </h3>
                                </div>
                                <div class="col-xs-5 text-right">
                                    <h3>
                                        <strong style="color: darkred;">$<span>{{checkOut.orderTotal.toFixed(2)}}</span></strong>
                                    </h3>
                                </div>

                            </div>


                            <div class="row">
                                <div class="col-xs-7 text-left">You saved:</div>
                                <div class="col-xs-5 text-right">
                                    $<span class="text-alert">{{checkOut.errors.toFixed(2)}}</span>
                                </div>
                            </div>

                            <div class="panel-footer">Shipping and handling haven't
                                applied.</div>
                            <br/><br/>
                            <button type="submit" class="btn btn-warning btn-block" id="submitorder">Place
                                your order</button>
                            <p style="font-size: smaller;">
                                By placing your order, you agree to Koly Style <a href="#">privacy</a>
                                notice and <a href="#">conditions</a> of use.
                            </p>    

                        </div>
                        </div>
                    </div>
                </div>
                </div>
            </div>
            </form>





        </div>
        </div>
        </section>
        <div class="clear"></div>

                </div>

                <script th:src="@{/js/controller.js}"></script>

                <!-- end of container -->
                <div th:replace="common/head :: footer" />

                <div th:replace="common/head :: body-bottom-scripts" />
            </div>
        </div>

    </div>
</div>

<script src="/js/demo.js"></script>
</body>
</html>

demo.js

'use strict';

(function () {
  var amount = document.querySelector('#amount');
  var amountLabel = document.querySelector('label[for="amount"]');

  amount.addEventListener('focus', function () {
    amountLabel.className = 'has-focus';
  }, false);
  amount.addEventListener('blur', function () {
    amountLabel.className = '';
  }, false);
})();

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.kolystyle</groupId>
    <artifactId>kolystyle</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>Kolystyle</name>
    <description>frontend of kolystyle</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- marked the embedded servlet container as provided -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
            <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
<dependency>
            <groupId>com.braintreepayments.gateway</groupId>
            <artifactId>braintree-java</artifactId>
            <version>2.73.0</version>
        </dependency>
    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

0 ответов

Другие вопросы по тегам