I do not know if there is a 'best' way to implement those two payments methods but here is what I have done on my project one month ago. Hope this helps.
Cheers.
1) override template 'oscar/checkout/payment_details.html' to list all available payment methods available to user (in my case : paypal, bankcheck and banktransfer).
Updated template should be located at 'my_project/templates/checkout/payment_details.html'
and oscar checkout app should have been forked (Oscar documentation explains how to fork an Oscar app).
For instance, code below allows user to choose 'banktransfer payment' in updated template :
payment_details.html
<div class="well">
<div class="sub-header">
<h3>{% trans "Bank Transfer payment" %}</h3>
</div>
<p>{% trans "Click on the below icon to use Bank Transfer payment . Bank details will be sent to you once order is validated :"%}
<div style="overflow:auto"><a href="{% url 'banktransfer-payment-details' %}" title="{% trans "Transfer" %}" class="btn btn-primary btn-md" role="button">{% trans "Continue" %}
</a> </div>
</div>
2) for 'my_project' project, create a new app for each new payment method (in my case, 2 new apps : bankcheck and banktransfer. I did not create a new app for paypal because I relied on django-oscar-paypal).
For each new app, subclass oscar class 'PaymentDetailsView' in app views.py and override method 'handle_payment', for instance :
views.py
class PaymentDetailsView(PaymentDetailsView):
template_name_preview = 'banktransfer/preview.html'
preview = True
[...]
def handle_payment(self, order_number, total, **kwargs):
"""
Complete payment with banktransfer
example total= Price(currency='EUR', excl_tax=Decimal('15.00'), incl_tax=Decimal('15.00'), tax=Decimal('0.00'))
"""
# Record payment source and event
source_type, is_created = SourceType.objects.get_or_create(
name='BankTransfer')
source = Source(source_type=source_type,
currency=total.currency,
amount_allocated=total.incl_tax,
amount_debited=0 # consider no payment so far
)
self.add_payment_source(source)
3) If needed, implement handle_post_checkout in order to catch checkout signal and do postprocessing when orders are checked out, for instance :
@receiver(post_checkout)
def handle_post_checkout(sender, **kwargs):
order = kwargs['order']
user = kwargs['user']
request = kwargs ['request']
response = kwargs ['response']
# new order : build invoice, send invoice to user, send email to admin, etc
...