Uber eats api 사용(oauth 포함)

조현준·2024년 6월 16일

잡다한거

목록 보기
4/5
post-thumbnail

진행 전 준비사항

  • 우버 developer application 생성
  • test 가게도 요청(우버에 요청)

우버 문서
https://developer.uber.com/docs/eats/introduction

axios 사용
어플리케이션과 우버 가게 연동(integration activation api)는 개발 실패.
연동은 되지만 어플리케이션으로 가게 관리가 안됨.(ex. 주문수락)
그래서 우버에 직접 요청(원하는 가게와 어플리케이션 연동)하면 해줌.

개발 목표

1. uber eats access token 가져오기

2. Uber Eats api를 사용해 가게에 들어온 주문 확인, 주문 accept, 주문 ready 개발, 주문 취소


1. uber eats access token 가져오기

우버는 2가지 액세스 토큰이 존재.
authorization 액세스토큰(provisioning): 어플리케이션과 가게를 연동할 때 사용하는 토큰. 로그인한 가게 정보 가져오는 토큰
client credentials 액세스토큰(eats order, store): 연동된 가게 주문 정보를 가져오는 토큰.

1.1) 로그인하기

  async uberAuthButtonClick() {
    const clientId = '우버 어플리케이션 id';
    const redirectUri = '나의 개발 url' + '/home';
    const scope = 'eats.pos_provisioning';
    const responseType = 'code';
    
    const _url = `https://login.uber.com/oauth/v2/authorize?client_id=${clientId}&response_type=${responseType}&redirect_uri=${redirectUri}`;

    Browser.open({ url: _url });
  }

1.2) 로그인하면 코드를 받고, 코드로 provisioning 액세스 토큰1 호출

	const tokenUrl = 'https://login.uber.com/oauth/v2/token';
	const params = new URLSearchParams({
      client_id: clientId,
      client_secret: clientSecret,
      grant_type: 'authorization_code',
      redirect_uri: redirectUri,
      code: code
	});

	try {
      const response = await axios.post(tokenUrl, params);
      // console.log('response success',response.data);
      res.send(response.data);
	} catch (error) {
      console.log(JSON.stringify(error));
      res.status(500).send('Internal Server Error');
	}

1.3) provisioning 액세스 토큰1으로 로그인한 가게 정보 가져오기

    const url = `https://api.uber.com/v1/delivery/stores`;
    
    const config = {
      headers: {
        'Authorization': accessToken,
        'Content-Type': 'application/json'
      }
    };

    try {
      const response = await axios.get(url, config);
      res.send(response.data);
    } catch (error) {
      console.error('Error', error);
      res.status(error.response ? error.response.status : 500).send('Failed Uber API');
    }

1.4) uber eats order, store 액세스 토큰2 호출

    const tokenUrl = 'https://auth.uber.com/oauth/v2/token';
    const params = new URLSearchParams({
      client_id: clientId,
      client_secret: clientSecret,
      redirect_uri: redirectUri,
      code: code,
      grant_type: 'client_credentials',
      scope: 'eats.order eats.store'
    });

    axios.post(tokenUrl, params)
    .then(response => {
      // console.log('response',response.data);
      res.send(response.data);
    })
    .catch(error => {
      console.log(error);
      res.status(500).send('Internal Server Error');
    })

1.5) 액세스 토큰2로 우버 어플리케이션에 있는 모든 가게 정보들 get

    const storeInfoUrl = 'https://api.uber.com/v1/delivery/stores';

    try {
      const response = await axios.get(storeInfoUrl, {
        headers: { 
          'Authorization': accessToken,
          'Content-Type': 'application/json'
        }
      });
      res.send(response.data);
    } catch (error) {
      console.error('Error fetching Uber stores:', error);
      res.status(error.response ? error.response.status : 500).send('Failed to fetch data from Uber API');
    }

1.6) 1.3에서 로그인한 가게 정보와 1.5에서 모든 가게 정보들 비교해서 같은 가게 있으면 연동(즉, 관련 데이터 저장하면 됩니다)


2. Uber Eats api를 사용해 가게에 들어온 주문 확인, 주문 accept, 주문 ready 개발, 주문 취소

  • 해당 api사용할 땐, client credentials 액세스토큰(uber eats order, store)으로 진행하는 것임!

2.1) uber webhook으로 주문 확인

  • 우버 어플리케이션에 일단 webhook 설정해주세요
// 우버 웹훅 받는 함수
webhook함수() {
		// order 상세 정보 가져오는 api 호출
        // 그리고 데이터 정제하고싶은 곳 처리하면 됩니다.
        const orderId = req.body.meta.resource_id;
        const expand = 'carts,deliveries,payment';
        const orderDetailUrl = `https://api.uber.com/v1/delivery/order/${orderId}?expand=${expand}`;
        const orderDetailConfig = {
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${accessToken}`
          }
        };

        let orderDetailData = {};

        await axios.get(orderDetailUrl, orderDetailConfig)
        .then(async (response) => {
          console.log('Order detail:', JSON.stringify(response.data));

          orderDetailData = response.data;
        }).catch(error => {
          console.log(error);
        });
    }

2.2) uber 주문 accept

    const acceptOrderUrl = `https://api.uber.com/v1/delivery/order/${orderId}/accept`;

    const acceptOrderConfig = {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`
      }
    };

    try {
      const response = await axios.post(acceptOrderUrl, {}, acceptOrderConfig);
      // console.log('Uber api response:', response.data);
      res.status(200).send(response.data);
    } catch (error) {
      console.error('Error accepting Uber order:', error);
      res.status(error.response ? error.response.status : 500).send('Failed to accept order');
    }

2.3) uber 주문 ready

    const readyOrderUrl = `https://api.uber.com/v1/delivery/order/${orderId}/ready`;
    const readyOrderConfig = {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`
      }
    };

    try {
      const response = await axios.post(readyOrderUrl, {}, readyOrderConfig);
      // console.log('Uber api response:', response.data);
      res.status(200).send(response.data);
    } catch (error) {
      console.error('Error readying Uber order:', error);
      res.status(error.response ? error.response.status : 500).send('Failed to ready order');
    }

2.4) uber 주문 취소

    const body = {
      info: canceled,
      type: cancelReason
    }

    const url = `https://api.uber.com/v1/delivery/order/${orderId}/cancel`;

    const config = {
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${accessToken}`
      }
    };

    try {
      const response = await axios.post(url, body, config);
      // console.log('Response:', response.data);
      res.send(response.data);
    } catch (error) {
      console.error('Error:', error);
      res.status(error.response ? error.response : 500).send('Failed to cancel order');
    }

0개의 댓글