/**
* Copyright (C) 2010-2017 Structr GmbH
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Structr. If not, see <http://www.gnu.org/licenses/>.
*/
package org.structr.payment.impl.stripe;
import com.stripe.Stripe;
import com.stripe.exception.APIConnectionException;
import com.stripe.exception.APIException;
import com.stripe.exception.AuthenticationException;
import com.stripe.exception.CardException;
import com.stripe.exception.InvalidRequestException;
import com.stripe.model.Charge;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.structr.api.config.Settings;
import org.structr.common.error.FrameworkException;
import org.structr.payment.api.APIError;
import org.structr.payment.api.BeginCheckoutResponse;
import org.structr.payment.api.CheckoutState;
import org.structr.payment.api.ConfirmCheckoutResponse;
import org.structr.payment.api.Payment;
import org.structr.payment.api.PaymentProvider;
import org.structr.payment.api.PaymentState;
/**
*
*/
public class StripePaymentProvider implements PaymentProvider {
private static final Logger logger = LoggerFactory.getLogger(StripePaymentProvider.class.getName());
@Override
public BeginCheckoutResponse beginCheckout(final Payment payment, final String successUrl, final String cancelUrl) throws FrameworkException {
throw new FrameworkException(422, "Begin checkout not supported by this payment provider. Please use the confirmCheckout endpoint.");
}
@Override
public ConfirmCheckoutResponse confirmCheckout(final Payment payment, final String notifyUrl, final String token, final String payerId) throws FrameworkException {
Stripe.apiKey = Settings.getStringSetting("stripe", "apikey").getValue();
// Create the charge on Stripe's servers - this will charge the user's card
try {
final Map<String, Object> chargeParams = new HashMap<>();
chargeParams.put("amount", payment.getTotal());
chargeParams.put("currency", payment.getCurrencyCode());
chargeParams.put("source", token);
chargeParams.put("description", payment.getDescription());
Charge.create(chargeParams);
payment.setPaymentState(PaymentState.completed);
return new ConfirmResponse(CheckoutState.Success);
} catch (APIException ex) {
payment.setPaymentState(PaymentState.error);
return new ConfirmResponse(CheckoutState.Failure, "1", "APIException", ex.getMessage());
} catch (APIConnectionException ex) {
payment.setPaymentState(PaymentState.error);
return new ConfirmResponse(CheckoutState.Failure, "1", "APIConnectionException", ex.getMessage());
} catch (InvalidRequestException ex) {
payment.setPaymentState(PaymentState.error);
return new ConfirmResponse(CheckoutState.Failure, "1", "InvalidRequestException", ex.getMessage());
} catch (AuthenticationException ex) {
payment.setPaymentState(PaymentState.error);
return new ConfirmResponse(CheckoutState.Failure, "1", "AuthenticationException", ex.getMessage());
} catch (CardException e) {
payment.setPaymentState(PaymentState.error);
return new ConfirmResponse(CheckoutState.Failure, e.getCode(), e.getCharge(), e.getMessage());
}
}
@Override
public void cancelCheckout(final Payment payment) throws FrameworkException {
// we only have to set the payment state
try {
payment.setToken(null);
payment.setPaymentState(PaymentState.cancelled);
} catch (FrameworkException fex) {
logger.warn("", fex);
}
}
private static class ConfirmResponse implements ConfirmCheckoutResponse {
private final List<APIError> errors = new LinkedList<>();
private CheckoutState state = null;
public ConfirmResponse(final CheckoutState state) {
this(state, null, null, null);
}
public ConfirmResponse(final CheckoutState state, final String errorCode, final String shortMessage, final String longMessage) {
this.state = state;
if (errorCode != null && shortMessage != null && longMessage != null) {
this.errors.add(new APIErrorImpl(errorCode, shortMessage, longMessage));
}
}
@Override
public CheckoutState getCheckoutState() {
return state;
}
@Override
public List<APIError> getErrors() {
return errors;
}
}
private static class APIErrorImpl implements APIError {
private String errorCode = null;
private String shortMessage = null;
private String longMessage = null;
public APIErrorImpl(final String errorCode, final String shortMessage, final String longMessage) {
this.errorCode = errorCode;
this.shortMessage = shortMessage;
this.longMessage = longMessage;
}
@Override
public String getShortMessage() {
return shortMessage;
}
@Override
public String getLongMessage() {
return longMessage;
}
@Override
public String getErrorCode() {
return errorCode;
}
}
}