Skip to content

Commit

Permalink
Merge pull request #4756 from mirumee/remove-all-static-payment-settings
Browse files Browse the repository at this point in the history
Remove all static payment settings
  • Loading branch information
korycins committed Sep 26, 2019
2 parents 7478b7c + 078f3d1 commit 73c1b26
Show file tree
Hide file tree
Showing 30 changed files with 153 additions and 175 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ All notable, unreleased changes to this project will be documented in this file.
- Unified MenuItemMove to other reordering mutations. It now uses relative positions instead of absolute ones (breaking change) - #4734 by @NyanKiyoshi.
- Add descriptions for queries and query arguments - #4758 by @maarcingebala
- Fixed the inability of users to set a variant's `priceOverride` and `costPrice` to `null` - #4754 by @NyanKiyoshi
- PaymentGatewayEnum removed from GraphQL schema as gateways now are dynamic plugins. Gateway names changed. - #4756 by @salwator
- Add support for webhooks - #4731 by @korycins

## 2.8.0
Expand Down
37 changes: 14 additions & 23 deletions saleor/core/payments.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,67 @@
from abc import ABC, abstractmethod
from enum import Enum
from typing import TYPE_CHECKING, List

if TYPE_CHECKING:
from saleor.payment.interface import PaymentData, GatewayResponse, TokenConfig


class Gateway(Enum):
"""Possible gateway values.
TODO: Create this in runtime based on available plugins
"""

DUMMY = "dummy"
BRAINTREE = "braintree"
RAZORPAY = "razorpay"
STRIPE = "stripe"


class PaymentInterface(ABC):
@abstractmethod
def list_payment_gateways(self) -> List[Gateway]:
def list_payment_gateways(self) -> List[str]:
pass

@abstractmethod
def authorize_payment(
self, gateway: Gateway, payment_information: "PaymentData"
self, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def capture_payment(
self, gateway: Gateway, payment_information: "PaymentData"
self, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def refund_payment(
self, gateway: Gateway, payment_information: "PaymentData"
self, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def void_payment(
self, gateway: Gateway, payment_information: "PaymentData"
self, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def confirm_payment(
self, gateway: Gateway, payment_information: "PaymentData"
self, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def process_payment(
self, gateway: Gateway, payment_information: "PaymentData"
self, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def create_payment_form(
self, data, gateway: Gateway, payment_information: "PaymentData"
self, data, gateway: str, payment_information: "PaymentData"
) -> "GatewayResponse":
pass

@abstractmethod
def get_client_token(self, gateway: Gateway, token_config: "TokenConfig") -> str:
def get_client_token(self, gateway: str, token_config: "TokenConfig") -> str:
pass

@abstractmethod
def list_payment_sources(
self, gateway: Gateway, customer_id: str
self, gateway: str, customer_id: str
) -> List["CustomerSource"]:
pass

@abstractmethod
def get_payment_template(self, gateway: str) -> str:
pass
2 changes: 1 addition & 1 deletion saleor/core/utils/random_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def create_fake_user():
@patch("saleor.order.emails.send_payment_confirmation.delay")
def create_fake_payment(mock_email_confirmation, order):
payment = create_payment(
gateway=settings.DUMMY,
gateway="Dummy",
customer_ip_address=fake.ipv4(),
email=order.user_email,
order=order,
Expand Down
3 changes: 3 additions & 0 deletions saleor/extensions/base_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ def create_form(self, data, payment_information, previous_value):
def get_client_token(self, token_config, previous_value):
return NotImplemented

def get_payment_template(self, previous_value):
return NotImplemented

@classmethod
def _update_config_items(
cls, configuration_to_update: List[dict], current_config: List[dict]
Expand Down
55 changes: 29 additions & 26 deletions saleor/extensions/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django_countries.fields import Country
from prices import Money, MoneyRange, TaxedMoney, TaxedMoneyRange

from ..core.payments import Gateway, PaymentInterface
from ..core.payments import PaymentInterface
from ..core.taxes import TaxType, quantize_price
from .models import PluginConfiguration

Expand All @@ -16,7 +16,7 @@
from ..product.models import Product
from ..account.models import Address, User
from ..order.models import OrderLine, Order
from ..payment.interface import PaymentData, GatewayResponse, TokenConfig
from ..payment.interface import PaymentData, TokenConfig


class ExtensionsManager(PaymentInterface):
Expand Down Expand Up @@ -203,38 +203,38 @@ def order_fulfilled(self, order: "Order"):
return self.__run_method_on_plugins("order_fulfilled", default_value, order)

def authorize_payment(
self, gateway: Gateway, payment_information: "PaymentData"
) -> "GatewayResponse":
self, gateway: str, payment_information: "PaymentData"
) -> Optional["GatewayResponse"]:
method_name = "authorize_payment"
return self.__run_payment_method(gateway, method_name, payment_information)

def capture_payment(
self, gateway: Gateway, payment_information: "PaymentData"
) -> "GatewayResponse":
self, gateway: str, payment_information: "PaymentData"
) -> Optional["GatewayResponse"]:
method_name = "capture_payment"
return self.__run_payment_method(gateway, method_name, payment_information)

def refund_payment(
self, gateway: Gateway, payment_information: "PaymentData"
) -> "GatewayResponse":
self, gateway: str, payment_information: "PaymentData"
) -> Optional["GatewayResponse"]:
method_name = "refund_payment"
return self.__run_payment_method(gateway, method_name, payment_information)

def void_payment(
self, gateway: Gateway, payment_information: "PaymentData"
) -> "GatewayResponse":
self, gateway: str, payment_information: "PaymentData"
) -> Optional["GatewayResponse"]:
method_name = "void_payment"
return self.__run_payment_method(gateway, method_name, payment_information)

def confirm_payment(
self, gateway: Gateway, payment_information: "PaymentData"
) -> "GatewayResponse":
self, gateway: str, payment_information: "PaymentData"
) -> Optional["GatewayResponse"]:
method_name = "confirm_payment"
return self.__run_payment_method(gateway, method_name, payment_information)

def process_payment(
self, gateway: Gateway, payment_information: "PaymentData"
) -> "GatewayResponse":
self, gateway: str, payment_information: "PaymentData"
) -> Optional["GatewayResponse"]:
method_name = "process_payment"
return self.__run_payment_method(gateway, method_name, payment_information)

Expand All @@ -247,43 +247,46 @@ def create_payment_form(self, data, gateway, payment_information):
def get_client_token(self, gateway, token_config: "TokenConfig") -> str:
method_name = "get_client_token"
default_value = None
gateway_name = gateway.value
gtw = self.get_plugin(gateway_name)
gtw = self.get_plugin(gateway)
return self.__run_method_on_single_plugin(
gtw, method_name, default_value, token_config=token_config
)

def list_payment_sources(
self, gateway: Gateway, customer_id: str
self, gateway: str, customer_id: str
) -> List["CustomerSource"]:
default_value = []
gateway_name = gateway.value
gtw = self.get_plugin(gateway_name)
gtw = self.get_plugin(gateway)
if gtw is not None:
return self.__run_method_on_single_plugin(
gtw, "list_payment_sources", default_value, customer_id=customer_id
)
raise Exception(f"Payment plugin {gateway_name} is inaccessible!")
raise Exception(f"Payment plugin {gateway} is inaccessible!")

def list_payment_gateways(self) -> List[Gateway]:
def list_payment_gateways(self) -> List[str]:
payment_method = "process_payment"
return [
Gateway(plugin.PLUGIN_NAME)
plugin.PLUGIN_NAME
for plugin in self.plugins
if payment_method in type(plugin).__dict__
and self.get_plugin_configuration(plugin.PLUGIN_NAME).active
]

def get_payment_template(self, gateway: str) -> str:
method_name = "get_payment_template"
default_value = None
gtw = self.get_plugin(gateway)
return self.__run_method_on_single_plugin(gtw, method_name, default_value)

def __run_payment_method(
self,
gateway: Gateway,
gateway: str,
method_name: str,
payment_information: "PaymentData",
**kwargs,
) -> Optional["GatewayResposne"]:
default_value = None
gateway_name = gateway.value
gtw = self.get_plugin(gateway_name)
gtw = self.get_plugin(gateway)
if gtw is not None:
resp = self.__run_method_on_single_plugin(
gtw,
Expand All @@ -296,7 +299,7 @@ def __run_payment_method(
return resp

raise Exception(
f"Payment plugin {gateway_name} for {method_name}"
f"Payment plugin {gateway} for {method_name}"
" payment method is inaccessible!"
)

Expand Down
2 changes: 1 addition & 1 deletion saleor/graphql/account/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def resolve_address_validation_rules(

def resolve_payment_sources(user: models.User):
stored_customer_accounts = (
(gtw, fetch_customer_id(user, gtw.value)) for gtw in gateway.list_gateways()
(gtw, fetch_customer_id(user, gtw)) for gtw in gateway.list_gateways()
)
return list(
chain(
Expand Down
3 changes: 1 addition & 2 deletions saleor/graphql/checkout/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from ..core.types.money import Money, TaxedMoney
from ..decorators import permission_required
from ..giftcard.types import GiftCard
from ..payment.enums import PaymentGatewayEnum
from ..shipping.types import ShippingMethod


Expand Down Expand Up @@ -49,7 +48,7 @@ class Checkout(MetadataObjectType, CountableDjangoObjectType):
description="Shipping methods that can be used with this order.",
)
available_payment_gateways = graphene.List(
PaymentGatewayEnum,
graphene.String,
description="List of available payment gateways.",
required=True,
)
Expand Down
3 changes: 1 addition & 2 deletions saleor/graphql/payment/enums.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import graphene

from ...graphql.core.enums import to_enum
from ...payment import GATEWAYS_ENUM, ChargeStatus
from ...payment import ChargeStatus

PaymentChargeStatusEnum = to_enum(ChargeStatus, type_name="PaymentChargeStatusEnum")
PaymentGatewayEnum = graphene.Enum.from_enum(GATEWAYS_ENUM)


class OrderAction(graphene.Enum):
Expand Down
3 changes: 1 addition & 2 deletions saleor/graphql/payment/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
from ..core.scalars import Decimal
from ..core.types import common as common_types
from ..core.utils import from_global_id_strict_type
from .enums import PaymentGatewayEnum
from .types import Payment


class PaymentInput(graphene.InputObjectType):
gateway = graphene.Field(
PaymentGatewayEnum,
graphene.String,
description="A gateway to use with that payment.",
required=True,
)
Expand Down
5 changes: 2 additions & 3 deletions saleor/graphql/payment/resolvers.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import graphene_django_optimizer as gql_optimizer

from ...core.payments import Gateway
from ...payment import gateway as payment_gateway, models
from ...payment.utils import fetch_customer_id
from ..utils import filter_by_query_param

PAYMENT_SEARCH_FIELDS = ["id"]


def resolve_client_token(user, gateway):
def resolve_client_token(user, gateway: str):
customer_id = fetch_customer_id(user, gateway)
return payment_gateway.get_client_token(Gateway(gateway), customer_id)
return payment_gateway.get_client_token(gateway, customer_id)


def resolve_payments(info, query):
Expand Down
4 changes: 1 addition & 3 deletions saleor/graphql/payment/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from ..core.fields import PrefetchingConnectionField
from ..decorators import permission_required
from .enums import PaymentGatewayEnum
from .mutations import PaymentCapture, PaymentRefund, PaymentSecureConfirm, PaymentVoid
from .resolvers import resolve_client_token, resolve_payments
from .types import Payment
Expand All @@ -19,8 +18,7 @@ class PaymentQueries(graphene.ObjectType):
payments = PrefetchingConnectionField(Payment, description="List of payments")
payment_client_token = graphene.Field(
graphene.String,
description="Return a new token for the payment gateway.",
gateway=graphene.Argument(PaymentGatewayEnum, description="A payment gateway."),
gateway=graphene.String(required=True, description="A payment gateway."),
)

@permission_required("order.manage_orders")
Expand Down
13 changes: 3 additions & 10 deletions saleor/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ type Checkout implements Node {
privateMeta: [MetaStore]!
meta: [MetaStore]!
availableShippingMethods: [ShippingMethod]!
availablePaymentGateways: [GatewaysEnum]!
availablePaymentGateways: [String]!
email: String!
isShippingRequired: Boolean!
lines: [CheckoutLine]
Expand Down Expand Up @@ -1601,13 +1601,6 @@ input FulfillmentUpdateTrackingInput {
notifyCustomer: Boolean
}

enum GatewaysEnum {
DUMMY
BRAINTREE
RAZORPAY
STRIPE
}

scalar GenericScalar

type Geolocalization {
Expand Down Expand Up @@ -2685,7 +2678,7 @@ enum PaymentErrorCode {
}

input PaymentInput {
gateway: GatewaysEnum!
gateway: String!
token: String!
amount: Decimal
billingAddress: AddressInput
Expand Down Expand Up @@ -3291,7 +3284,7 @@ type Query {
reportProductSales(period: ReportingPeriod!, before: String, after: String, first: Int, last: Int): ProductVariantCountableConnection
payment(id: ID!): Payment
payments(before: String, after: String, first: Int, last: Int): PaymentCountableConnection
paymentClientToken(gateway: GatewaysEnum): String
paymentClientToken(gateway: String!): String
page(id: ID, slug: String): Page
pages(query: String, filter: PageFilterInput, before: String, after: String, first: Int, last: Int): PageCountableConnection
homepageEvents(before: String, after: String, first: Int, last: Int): OrderEventCountableConnection
Expand Down
5 changes: 1 addition & 4 deletions saleor/order/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@


def get_gateways():
gateways = [
(gtw.value, gtw.value.capitalize() + " gateway")
for gtw in gateway.list_gateways()
]
gateways = [(gtw, gtw.capitalize() + " gateway") for gtw in gateway.list_gateways()]
return gateways


Expand Down

0 comments on commit 73c1b26

Please sign in to comment.