I try to implement 2checkout to my django app (Python 3.7 and Django 2.2).
I'm using the Sandox and when I see API logs my orders are successfully passed. I also chose a URL for the Passback and selected Header Redirect in my account settings.
Unfortunately, I don't succeed in getting the redirection works :
I get this error after twocheckout.Charge.authorize(params) if successfully executed:
The view subscriptions.views.subscription_payment didn't return an HttpResponse object. It returned None instead.
When I manually add an HttpResponseRedirect like this:
return HttpResponseRedirect('/payment-success') the GET request is empty because it doesn't come from 2checkout.
I tried to follow this tutorial https://github.com/2Checkout/2checkout-python-tutorial and it doesn't mention any HttpResponseRedirect.
Could you please help me with this issue? It's really frustrating. I'm a beginner developper so maybe I missed something. Please feel free to ask any further information that would be helpful to understand my issue.
Many thanks in advance
I was integrating the API so no need for Passback URL. The question was a non sense :) That's why the tutorial doesn't mention HttpResponseRedirect.
Because it has been asked in the comments, here is the code used to fulfil the need I had at that moment. Hope this could help someone else.
def subscription_payment(request, pk):
property = Property.objects.get(pk=pk)
if request.method == 'POST':
pay_token = request.POST.get('token')
twocheckout.Api.auth_credentials({
'private_key': '######-####-####-####-#######',
'seller_id': '#########',
'mode': 'sandbox' # Uncomment to use Sandbox
})
data = serializers.serialize('json', Profile.objects.filter(user=request.user), fields=(
'address_2', 'city', 'zip_code', 'country', 'phone_number'))
data = json.loads(data)
params = {
'merchantOrderId': request.user.id,
'token': pay_token,
'currency': 'USD',
'billingAddr': {
'name': request.user.get_full_name(),
'addrLine1': data[0]['fields']['address_2'],
'city': data[0]['fields']['city'],
'state': ' ',
'zipCode': data[0]['fields']['zip_code'],
'country': data[0]['fields']['country'],
'email': request.user.email,
'phoneNumber': data[0]['fields']['phone_number'],
},
'lineItems': [
{
'type': 'product',
'name': 'Abonnement mensuel basic',
'recurrence': '1 Month',
'duration': '3 Month',
'tangible': 'N',
'price': '150.00',
'description': '',
'productId': property.id,
}
]
}
try:
result = twocheckout.Charge.authorize(params)
backup_response = json.dumps(result)
print(result.responseCode)
if result.responseCode == 'APPROVED':
offer = Offer.objects.get(type='MONTHLY_BASIC')
user = request.user
payment_data = dict()
payment_data['response_code'] = result.responseCode
payment_data['transaction_id'] = result.transactionId
payment_data['order_number'] = result.orderNumber
payment_data['amount'] = result['lineItems'][0]['price']
payment_data['property_title_bkp'] = property.title
payment_data['backup_response'] = backup_response
Payment.objects.create(
offer=offer,
property=property,
user=user,
initiated_on=timezone.now(),
**payment_data
)
return render(request, 'subscriptions/payment_success.html', payment_data)
except TwocheckoutError as error:
return HttpResponse(error.msg)
Related
I'm trying to update the body field from the payrun_chatter_log() but it won't update. any idea on how to do this? This is what I did:
def payrun_chatter_log(self):
subtype = self.env['mail.message.subtype'].search([('id','=', '2')])
vals = {
'date': fields.datetime.now(),
'email_from': self.env.user.email_formatted,
'author_id': self.env.user.id,
'message_type': 'notification',
'subtype_id': subtype.id,
'is_internal': True,
'model': 'custom.module',
'res_id': self.id,
'body': 'Test'
}
self.env['mail.message'].create(vals)
def custom_button(self):
chatter = self.env['mail.message'].search([('res_id', '=', self.id)])
message = 'Custom Message here'
chatter.update({'body': message})
return super(CustomModule, self).custom_button()
Your below line of code in custom_button will return multi record because res_id will be repeated for more than one model
chatter = self.env['mail.message'].search([('res_id', '=', self.id)])
You need to add the model to search:
chatter = self.env['mail.message'].search([('model', '=', self._name), ('res_id', '=', self.id)])
The message body should be updated, you need to refresh the page to see the changes.
Try to return the following client action:
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
The chatter has an One2many relation to mail.message model. Your function will update all messages
I have tried stripe but the problem is that in the docs they have listed that for accepting international payments from India, I have to be registered and also I need to add billing address, name of the customer and the payment intent. They have provided documentation on how to add names and payment intent, but I don't know how to implement the provided code in my application.
So, pls tell me how to do it...
Just in case you, this is my checkout code
#app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price_data': {
'currency': 'usd',
'product_data': {
'name': 'T-shirt',
},
'unit_amount': 2000,
},
'quantity': 1,
}],
mode='payment',
success_url=redirect("success.html"),
cancel_url=redirect("cancel.html"),
)
If you're using Stripe Checkout you don't need to change your code; Checkout will collect the required information from your customer (name and billing address) on the Checkout page.
Edited respons
This is how you can add other optional params:
#bp.route('/create-checkout-session')
def create_checkout_session():
domain_url = 'http://localhost:5000/'
stripe.api_key = current_app.config['STRIPE_SECRET_KEY']
try:
checkout_session = stripe.checkout.Session.create(
success_url=domain_url + 'success',
cancel_url=domain_url + 'cancelled',
payment_method_types=['card'],
billing_address_collection='required',
mode='payment',
customer='customer_id',
line_items=[
{
# using the price api takes care of the product well
# rather than having to specify name, currency etc
'quantity': 1,
'price': 'price_1IYgbtFWpU2KHaPLODAVgoKU'
}
],
payment_intent_data=[
{
# Place your data here
'param-key': 'value',
# ...
}
]
)
# your return statement
except Exception as e:
# your return statement
You can do this for the other params
I am trying to pass multiple parameters to hotel offers using the Amadeus Python SDK but I am getting a 400 error code. How can I include checkInDate and checkOutDate in the request?
here's the code :
amadeus = Client(
client_id = clientID,
client_secret = ClientSecret
)
try:
hotels_by_city = amadeus.shopping.hotel_offers.get(cityCode=citycode,checkInDate=checkindate,checkOutDate=checkoutdate,adults=adults,roomQuantity=rooms)
k = hotels_by_city.data
print(k)
Here an example of how to use the Python SDK to implement Hotel Search and Book:
# Install the Python library from https://pypi.org/project/amadeus
from amadeus import Client, ResponseError
amadeus = Client(
client_id='YOUR_AMADEUS_API_KEY',
client_secret='YOUR_AMADEUS_API_SECRET'
)
try:
# Get list of Hotels by city code
hotels_by_city = amadeus.shopping.hotel_offers.get(cityCode='PAR', checkInDate='2021-01-10', checkOutDate='2021-01-12')
# Get list of offers for a specific hotel
hotel_offers = amadeus.shopping.hotel_offers_by_hotel.get(hotelId = 'HSMADAMI', checkInDate='2021-01-10', checkOutDate='2021-01-12')
# Confirm the availability of a specific offer
offer = hotel_offers.data['offers'][0]['id']
offer_availability = amadeus.shopping.hotel_offer(offer).get()
guests = [{'id': 1, 'name': { 'title': 'MR', 'firstName': 'BOB', 'lastName': 'SMITH' }, 'contact': { 'phone': '+33679278416', 'email': 'bob.smith#email.com'}}]
payments = { 'id': 1, 'method': 'creditCard', 'card': { 'vendorCode': 'VI', 'cardNumber': '4151289722471370', 'expiryDate': '2021-08' } }
hotel_booking = amadeus.booking.hotel_bookings.post(offer, guests, payments)
print(hotel_booking.data)
except ResponseError as error:
raise error
I'm using Google AdWords Python SDK to create ResponsiveDisplayAds. My code is like below.
adgroup_ad_service = adwords_client.GetService(
service_name = "AdGroupAdService",
version = "v201809"
)
operations = [{
'operator': 'ADD',
'operand': {
'xsi_type': 'AdGroupAd',
'adGroupId': '<AD_GROUP_ID>',
'ad': {
'xsi_type': 'ResponsiveDisplayAd',
'marketingImage': {
'mediaId': '<MEDIA_ID>'
},
'shortHeadline': 'Short Headline',
'longHeadline': 'This is a very long headline',
'description': 'This is a description',
'businessName': 'Test Business Name',
'finalUrls': ['https://www.google.com'],
'squareMarketingImage': {
'mediaId': '<MEDIA_ID>'
}
},
'status': 'PAUSED'
}
}]
ads_response = adgroup_ad_service.mutate(operations)
print("AD RESPONSE : {}".format(ads_response))
But It's giving me, AdGroupAdError.CANNOT_CREATE_DEPRECATED_ADS.
According to the documentation it describe this error as An ad of this type is deprecated and cannot be created. Only deletions are permitted..
But in documentation of the AdGroupAd ResponsiveDisplayAd, is one of the accepted Ad types.
So it would be great if someone can point me a direction to resolve this issue.
Use AddMultiAssetResponsiveDisplayAd instead.
Same result in a different way.
Hope you can make it like i did.
I am writing a method that it first will retrieve the current context from the model then using context.update() to add on new values for the context. I also tried to use the current method self.with_context() but still no success since the context values seem frozen and could not be passed in. I read online from some source that there is a way to override the name_get(). But the source only briefly reference, there would be no clear instruction so that i can follow. I am new in Odoo and the problem between v7 and v8 its killing me. Please help me revise my following source code:
def get_print_report(self):
domain = [('effective_date', '>=', self.from_date),
('effective_date', '<=', self.to_date),
('employee_id', 'in', self.employee_ids.ids),
('department_id', '=', self.department_id.id),
('job_id', '=', self.job_id.id)]
list_view = self.env.ref(
'trainingwagekp.payroll_wage_hist_wizard_tree_view')
context = self._context.copy()
if context is None:
context = {}
if context.get('order_by', False):
context.update({'default_order': self.order_by + ' desc'})
self.with_context(context)
print '===============', self._context
return{'name': 'Wage History Report',
'view_type': 'form',
'view_mode': 'tree',
'view_id': list_view.id,
'res_model': 'trobz.payroll.wage.history',
'type': 'ir.actions.act_window',
'context': context,
'domain': domain,
}
Please also let me know which is the best way to modify context in Odoo 8. Thanks
You already passing new context in return. Just remove self.with_context(context) line. As per below code.
def get_print_report(self):
domain = [('effective_date', '>=', self.from_date),
('effective_date', '<=', self.to_date),
('employee_id', 'in', self.employee_ids.ids),
('department_id', '=', self.department_id.id),
('job_id', '=', self.job_id.id)]
list_view = self.env.ref(
'trainingwagekp.payroll_wage_hist_wizard_tree_view')
context = self._context.copy()
if context is None:
context = {}
if context.get('order_by', False):
context.update({'default_order': self.order_by + ' desc'})
return{'name': 'Wage History Report',
'view_type': 'form',
'view_mode': 'tree',
'view_id': list_view.id,
'res_model': 'trobz.payroll.wage.history',
'type': 'ir.actions.act_window',
'context': context,
'domain': domain,
}
I think if you check the type of context, you will find that it is a frozen dict. You shall change it to a dict context = dict(self._context) then do all the alteration you need then turn it back into a frozen dict and give